[英]Networking completion block, recursion and ARC retain cycle
这是一个棘手的问题,答案可能对许多网络学徒有用,包括我。
关于上下文的一些背景信息:
一种巧妙的方法是使用递归。 您可以提出的常见实现的问题是网络完成块和自身之间的保留周期。 这可以使用weakSelf参考指针来解决。
但是,保留递归调用的周期呢?
我们已经实现了一个递归堆栈,自我指向下载管理类,如下所示:
-(void)startNetworkDownloadForObjectAtIndex:(int) anIndex
{
__typeof__(self) __weak weakSelf = self;
NSURL *urlForObjectAtIndex = [SomeClass URLforIndex:anIndex];
[self.downloadManager getResourceAtURL:urlForObjectAtIndex success:^(AFHTTPRequestOperation *operation, id responseObject) {
if (indexOfObjectToDownload < weakself.totalNumberOfObjectsToDownload) [weakSelf startNetworkDownloadForObjectAtIndex:indexOfObjectToDownload+1];
else [weakSelf startDOwnloadTimer];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// response code is in operation.response.statusCode
[weakSelf handleNetworkError:error];
}];
}
-(void)handleNetworkError:error
{
// Do some error handling
[self startNetworkDownloadForObjectAtIndex:self.lastUnsentObjectIndex];
}
-(void)startDownloadTimer
{
if (self.syncEngineTimer) [self.syncEngineTimer invalidate];
self.syncEngineTimer = [NSTimer scheduledTimerWithTimeInterval:kSyncTimeInterval
target:self
selector:@selector(restartNetworkDownload)
userInfo:nil
repeats:NO];
}
-(void)restartNetworkDownload
{
// do some fancy calculations / etc to manage your download
int anIndex = theResultOfYourCalculation;
[self startNetworkDownloadForObjectAtIndex:anIndex];
}
好的,这是一个可能的递归调用几个网络下载的例子(例如获得100个闪烁的图片),并尝试在1小时后获得新的网络。 请原谅任何编码错别字。
我们在ARC下为iOS 5.0以上的iOS设备运行此功能
当使用self.downloadManager保持对成功和失败完成块的引用时,我们显然通过使用weakSelf引用指针打破了第一级保留周期。 这一切都很好,在乐器中也很顺利。
现在,在查看Instruments中的分配时,我们会启动下载操作以进行多次下载。 仪器没有泄漏。 但是当重新保存堆时,你可以看到它慢慢增长。
检查分配并查看调用堆栈,看起来块看起来像是通过使用startDownloadTimer来保持对self的引用
任何可能的原因和解决方案的解释将不胜感激:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.