Cocoa中编写你自己的变参格式化函数

问题背景

近几天,手头做的Mac下的新浪微博客户端Miao的就要收工了,在做一些代码优化方面的工作。其中就遇到了这么一个具体的问题。客户端核心引擎会统一向新浪发送不同的请求。当然这些请求是针对统一域的,但是携带不同的参数。例如:

http://api.weibo.com/statuses/friends.json?source=xxxxxx&screen_name=abc
http://api.weibo.com/statuses/friends.json?source=xxxxxx&screen_name=abc&count=100
http://api.weibo.com/statuses/public_timeline.json?source=xxxxxx&page=1&count=200
http://api.weibo.com/comments/timeline.json?source=xxxxxx&count=100

显然,程序需要在每个请求函数里建立这样一个请求的url地址。那么如何统一处理这些请求地址呢?这篇文章会向大家介绍一个C程序员都知道,但是又比较冷的技术,来处理这个问题。

构造上述地址是很麻烦,因此我为引擎写了一个统一构造url的函数。

- (NSURL*)url:(NSString*)subpath;

该函数接受一个子目录字符串作为参数。然后返回完整 url。例如:[self url:@"comments/timeline.json?count=100"]; 返回 http://api.weibo.com/comments/timeline.json?count=100

这样很好,整个引擎可以很轻松的更换domain、source等参数。但是每次构造复杂的请求都要自己格式化一个subpath字符串进去。确实有点丑陋。例如这样:[engine url:[NSString stringWithFormat:@"comments/timeline.json?count=%d&page=%d",num,page]];

是否可以做一些优化呢?!

模仿NSLog

如果是模仿NSLog这样如何?会比上面简洁不少的。

[engine url:@"comments/timeline.json?count=%d&page=%d", num, page];

模仿NSLog? 好吧,其实应该说模仿c语言里的printf。这是个很古老的概念了Variable Argument Lists Function,变参函数。用在这里真的再适合不过了。

Cocoa里写变参函数

我承认在写C的年代里自己就很少写变参函数,不过在Cocoa里写变参函数和C是一样的,唯一要注意的就是怎么把它引导到NSString里!既然这个问题用它非常适合,那么就稍微尝试改写一下url函数吧。

- (NSURL*)url:(NSString*)subpathformat, ...
{
    va_list args;
    va_start (args, subpathformat);
    NSString *subpath = [[NSString alloc] initWithFormat: subpathformat  arguments: args];
    va_end (args);

    NSString *urlstring=[NSString stringWithFormat:@"%@://%@/%@", secureConnection?@"https":@"http", APIDomain, subpath];
    if ([subpath rangeOfString:@"?"].location==NSNotFound) {
        urlstring=[NSString stringWithFormat:@"%@?source=%@",urlstring,consumerKey];
    }else{
        urlstring=[NSString stringWithFormat:@"%@&source=%@",urlstring,consumerKey];
    }
    urlstring=[urlstring stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    return [NSURL URLWithString:urlstring];
}

经过改写可以看到NSString类很贴心的准备了initWithFormat:arguments:构造函数。基本上一句话就可以处理掉传入的参数小朋友们了!

总结

其实大家都明白的。变参函数,对于一般程序员写代码是冷门语法。不过,推荐遇到相似问题的Cocoa程序员可以尝试多用用这个技巧。代码优美了你也会更珍惜自己的创作的。