食谱实现自保留网络库

时间:2014-04-30 18:30:13

标签: objective-c automatic-ref-counting objective-c-blocks

我想实现一个可以与ARC一起使用的自保留网络库。

此lib的调用代码应如下所示。

- (void)downloadData {

    NSURL *url = // alloc-init
    NetworkFetcher *networkFetcher = [[NetworkFetcher alloc] initWithURL:url];
    [networkFetcher startWithCompletionHandler:^(NSData *data){
        _fetchedData = data;
    }];
    // under ARC it will put a release call for the networkFetcher here
}

这种方法在Twitter框架中由TWRequest使用(如果我没有错,现在已弃用)。优点是调用者不需要自己维护fetcher。

一些细节。 startWithCompletionHandler复制块以供将来重用。请求完成后,fetcheher会将块settima释放为nil。

那么,我需要遵循什么方法,以便抓取器可以自我保留?有没有最好的实践?

2 个答案:

答案 0 :(得分:2)

您可以添加“私人”属性

@interface NetworkFetcher ()
@property (strong, nonatomic) NetworkFetcher *selfRef;
@end

NetworkFetcher类的类扩展中。在startWithCompletionHandler中,您设置了

self.selfRef = self;

防止对象被释放。请求完成并调用完成块后,设置

self.selfRef = nil;

破坏保留周期。

答案 1 :(得分:1)

我通常使用Martin R描述的技术,它基本上模仿较旧的retainrelease,但也有其他方法。

您可以捕获fetcher中的completionHandler。只需在完成处理程序中的任何位置使用self,并且在调用块时不要忘记释放块。这比使用属性的可读性稍差,但它遵循相同的原则

另一种方法是使用单个(可变)活动提取器数组。添加/删除遵循与self.selfRef属性相同的原则。

使用单例阵列有一个很大的优势 - 您可以随时访问取出器 - 取消它们或只获取活动取出器的数量(例如,限制同时下载的数量)。