2013-02-07 51 views
4

我在委託方法內創建了一個塊,並使用它在另一個類中調用靜態方法。即使啓用NSZombies,我也會收到EXC_BAD_ACCESS錯誤。這裏對於有關類似問題的幾個職位 - 我覺得這一個是最接近:ARC:EXC_BAD_ACCESS在委託方法內從塊內調用方法

ARC: Getting EXC_BAD_ACCESS from inside block used in delegate method

但是,我沒有發現任何東西至今已幫助。下面是代碼:

@interface MyClass() 
@property (nonatomic, copy) CaseBlock c; 
@end 

.... 

//NSURLConnection delegate method 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{   
    NSDictionary *d = [NSDictionary dictionaryWithObjectsAndKeys: 
         //blows up after executing this 
         ^() { [AnotherClass staticMethod]; },authURL, 
         ^() { NSLog(@"TODO");}, searchURL, 
         ^() { NSLog(@"TODO"); }, itemURL, 
         nil]; 
    self.c = [[d objectForKey:[self.url path]] copy]; 

    if (self.c) { 
     self.c(); 
    } else { NSLog(@"WARN unexpected response path"); } 

} 

這是我曾嘗試使用塊的第一次,但我可以告訴大家,這是造成問題,因爲調用外部塊正常工作的方法。而且,據我所知,我寫的所有代碼都會被執行,然後發生EXC_BAD_ACCESS錯誤。但是,我是Objective-C的新手,所以如果我錯了,請糾正我。

+0

我做了一個更簡化的示例代碼版本,並沒有得到崩潰。你說它在實例化字典時崩潰了? –

+0

不完全超熟悉塊,但我的猜測是塊不是對象(就像一個int),所以你不能把它當作一個對象,因此你不能把它放到字典中。 – TheAmateurProgrammer

+1

@TheAmateurProgrammer塊可以視爲對象('id')。據我所知,他們只響應一個選擇器「副本」。如果從內存堆棧複製它們,可以安全地存儲在集合中。 – Tricertops

回答

9

如果需要超出創建的範圍,則需要複製塊。由於dictionaryWithObjectsAndKeys:處理的是一般對象而不是特定塊,因此它不知道複製它們,所以您必須先複製它們,然後再通過它們到它。

NSDictionary *d = [NSDictionary dictionaryWithObjectsAndKeys: 
        //blows up after executing this 
        [^() { [AnotherClass staticMethod]; } copy], authURL, 
        [^() { NSLog(@"TODO");} copy], searchURL, 
        [^() { NSLog(@"TODO"); } copy], itemURL, 
        nil]; 
+0

哦!是的,我認爲這是問題,但我也認爲這個副本處理它:self.c = [[d objectForKey:[self.url path]] copy];謝謝 - 它現在有效。 – minus

+0

@CarolineM:堆棧塊只在聲明的範圍內有效(在這種情況下,它被用作方法調用的參數,所以它的範圍就是該方法調用)。您需要在它無效之前將其複製,並且由於該方法不會爲您複製它,所以您必須在將該塊傳遞給方法之前將其複製 – newacct