2012-07-11 27 views
3

在執行涉及objective-c塊的遞歸時,我在iOS應用程序中接收到EXC_BAD_ACCESS信號。下面是簡化的代碼:使用objective-c中的塊遞歸

- (void)problematicMethod:(FriendInfo*)friendInfo onComplete:(void(^)(NSString*))onComplete1 { 

[self doSomethingWithFriend:friendInfo onComplete:^(Response* response) { 
    switch (response.status) { 
     case IS_OK: 
      onComplete1(message); 
      break; 

     case ISNT_OK: 
      // Recursively calls the method until a different response is received 
      [self problematicMethod:friendInfo onComplete:onComplete1]; 
      break;   

     default: 
      break; 
    } 
}]; 
} 

所以基本上,problematicMethod,在這個簡化版本,來電doSomethingWithFriend:的onComplete:。當該方法完成時(onComplete),如果一切正常,將調用原始的塊,並且這可以正常工作。

但是如果出現問題,需要再次調用問題方法(遞歸部分),並且當第一次發生這種情況時,我立即得到EXC_BAD_ACCESS信號。

任何形式的幫助將不勝感激。

+0

坦率地說,我不知道直接的EXC_BAD_ACCESS來自哪裏。順便說一句,如果你提供了一些關於異常的更多信息,這將會很有幫助。調試器對此有何評論?無論如何,如果您懷疑遞歸方法對EXC_BAD_ACCESS負責,那麼爲什麼不使用performSelector調用problematicMethod:withObject:afterDelay:? withObject可能爲零,afterDelay甚至可能爲0. – 2012-07-11 08:40:14

+0

@HermannKlecker實際上沒有什麼更多的調試器可以告訴我。由於讀取了不正確的數據(例如NSArray變量指向NSConcreteData數據),EXX_BAD_ACCESS會在第一次從ISNT_OK調用[self problem ...]方法或第二次進入方法時發生。 – Misa 2012-07-11 12:52:55

+0

而我越看越,我越確定使用錯誤的內存位置來訪問數據。我試圖用[block copy]複製每一個塊,並且泄漏內存(沒有autorelease),但沒有任何運氣。 – Misa 2012-07-11 12:55:28

回答

2

你是如何創建你的區塊?請記住,您必須將其從堆棧移動到堆。

例子:

 void(^onCompleteBlock)(NSString*) = [[^(NSString* param) { 
    //...block code 
}] copy] autorelease];

[self problematicMethod:friendInfo onCompleteBlock];

+0

我試過了,儘管它看起來像一個完美的解決方案,但它不起作用。 – Misa 2012-07-11 12:57:01

+0

這是不正確的。調用代碼不需要複製它,因爲它沒有存儲在任何地方。 – newacct 2012-07-11 19:51:10

+0

@newacct塊在堆棧上創建。複製塊將其從堆棧移動到堆。我認爲這是非常重要的,當這個塊被傳遞給一個響應處理程序並在將來某個未知的時間使用時。 – Sulthan 2012-07-11 20:03:21

0

如果response.status值ISNT_OK你永遠不會完成遞歸調用該函數。