2012-07-10 32 views
2

我想了解在操作的完成塊中引用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。

仍然不知道如何解決這個..

+0

這是一個ARC項目? – 2012-07-10 17:53:26

+0

請看看我的更新 – Eyal 2012-07-11 07:38:05

+0

它是一個ARC項目(因爲'__block'的語義在ARC下是不同的),並且您的部署目標是5.0+嗎? – 2012-07-11 15:36:34

回答

2
[[AppClient sharedClient] sendCommand:@"getpicture" parameters:cmdParameters success:^(AFHTTPRequestOperation *operation, id response) 
    { 
     if(!operation.isCancelled) 
     { 
     // success 
     UIImage *downloadedImage = ...; // get image from response 

     weakSelf.picture = downloadedImage; // set image to user's picture property 
     } 
    } 
+0

如果操作被取消,則不會調用成功塊,所以我不認爲這是必需的。 – Eyal 2012-07-10 11:52:42

+0

我檢查了操作狀態,它是「isFinished」,怎麼樣?那很混亂:( – Eyal 2012-07-10 12:03:06

+0

請看我更新的問題 – Eyal 2012-07-11 07:38:26