這是一個棘手的問題,答案可能證明對包括我在內的許多網絡學徒有用。網絡完成塊,遞歸和ARC保留週期
上下文的一些背景資料:
- 比方說,你想從下載數據的在線服務 要做到這一點
- 異步 你想在同一時間做一個下載
- ,那麼也許在完成之前做一個。
這樣做的一個簡單方法是使用遞歸。 您可以想到的常見實現的問題是在網絡完成塊和自我之間保留週期。這可以使用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];
}
OK,這是幾個網絡下載一個可能的遞歸調用的例子(獲得100張閃爍圖片例如),並嘗試在1小時後得到新的。 原諒任何編碼錯別字。
我們ARC下運行這個上面的iOS iOS設備5.0
很明顯,我們通過使用self.downloadManager保持的成功和失敗結束時的參考使用weakSelf參考指針打破保留週期的第一級塊。這一切都很好,在樂器中表現良好。
現在,在查看Instruments中的分配時,我們啓動了多個下載的下載操作。儀器不顯示泄漏。 但是當正在儲存堆時,您可以看到它正在慢慢增長。
檢查分配和具有一看調用堆棧,它肯定看起來像塊被保持於自基準通過使用startDownloadTimer
上的可能原因和解決方案的任何解釋的,將不勝感激:)
這太複雜了。您可以在操作隊列上安排下載並設置併發下載數量,在網絡操作中設置超時時間,並在完成處理程序中從網址池中刪除要下載的URL。不需要遞歸。 NSTimer很容易產生週期,例如https://gist.github.com/j4n0/5575264以獲得安全使用。 – Jano
@ChevenementDavid:這裏沒有遞歸。完成塊是從事件循環中調用的,而不是源代碼中包含它們的方法。但否則,這個問題是相關的。 – Codo
@codo,遞歸確實存在:你不斷添加遞歸調用startDownloadingObjectAtIndex,並且只有在遞歸結束時,纔會啓動計時器。 –