我想了解在操作的完成塊中引用Object時,是否讓Object在其dealloc方法中取消網絡操作是個好主意。目標c - 取消dealloc中的操作
我會嘗試用一個例子來解釋:
我有物業picture
一個User
對象,User
有[self fetchPictureFromServer]
:
- (void)fetchPictureFromServer
{
NSDictionary *cmdParameters = ...; // set parameters
__block User *weakSelf = self;
[[AppClient sharedClient] sendCommand:@"getpicture" parameters:cmdParameters success:^(AFHTTPRequestOperation *operation, id response)
{
// success
UIImage *downloadedImage = ...; // get image from response
weakSelf.picture = downloadedImage; // set image to user's picture property
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// failed
}];
的sendCommand
方法將創建(和入隊NSOperationQueue
)一個NSOperation
,在時間上將啓動一個NSURLConnection
下載圖像。當操作成功完成時,將調用成功塊。我使用weakSelf
,因爲我不希望塊保留我的用戶對象(並防止它成爲dealloc),我希望用戶將負責取消現有的操作(如果存在),當他得到dealloc。
所以用戶dealloc方法是這樣的:
- (void)dealloc
{
[[AppClient sharedClient] cancelAllCommandsForSender:self];
[super dealloc];
}
但似乎,雖然我在取消dealloc方法操作,有時成功的塊被稱爲用戶後得到的dealloc,我獲得EXC_BAD_ACCESS
,行weakSelf.picture = downloadedImage
。
爲什麼會發生?即使它被取消,操作是否會嘗試完成連接?
我知道,如果我只在塊中使用self而不是weakSelf,則不會發生這種情況,因爲該塊將保留用戶。但我不想要這種行爲,我希望用戶在釋放時立即獲得dealloc,即使存在獲取操作。
UPDATE: 我注意到,工作狀態isFinished = YES,似乎與我使用的庫,當操作完成後,它不會立即執行成功的塊,但它dispatch_async的成功阻止主隊列。
那麼正常發生的事情是:
1.用戶獲取圖像 - 之前的成功塊> dispatch_async成功塊(還沒有執行)
3 - >操作創建
2.操作完成執行用戶dealloc - >取消他所有的操作(但不是從step1開始的操作,因爲它處於isFinished狀態)
4.現在執行成功塊 - >當嘗試引用用戶時,我得到EXC_BAD_ACCESS。
仍然不知道如何解決這個..
這是一個ARC項目? – 2012-07-10 17:53:26
請看看我的更新 – Eyal 2012-07-11 07:38:05
它是一個ARC項目(因爲'__block'的語義在ARC下是不同的),並且您的部署目標是5.0+嗎? – 2012-07-11 15:36:34