2015-04-07 46 views
1

對象在ARC模式下解除分配並導致崩潰。我的代碼在下面;對象在ARC模式下解除分配

BlockAlertView* alert = [BlockAlertView alertWithTitle:title message:message]; 
[alert setCancelButtonWithTitle:NSLocalizedString(@"No", @"No Button") block:nil]; 
[alert addButtonWithTitle:NSLocalizedString(@"Yes", @"Yes Button") block:^{ 
     //Do Something 
}]; 
[alert show]; 

它看起來是正確的警報視圖(這是自定義UIView),但當我點擊其中一個按鈕它崩潰。

崩潰日誌;

2015-04-07 22:28:17.065 Test[3213:781570] <BlockAlertView: 0x16bb4160> 2015-04-07 22:33:01.746 Test[3213:781570] *** -[BlockAlertView performSelector:withObject:withObject:]: message sent to deallocated instance 0x16bb4160

這裏是BlockAlertView的源代碼;

BlockAlertView on Github

現在我不能估計任何線索這個的,使我老了。 任何輸入將不勝感激!

+0

什麼是'BlockAlertView'?顯示它的代碼。 – Wain

+0

這是我寫的並且比較長。不知道如何向你展示,甚至它在那裏,它可以成爲釋放的原因嗎? – vichevstefan

+0

當然,創建和調用'show'本身並不是'alert'被保留的原因... – Wain

回答

1

推測該代碼在轉換爲ARC之前工作正常。

要解決它,你需要創建在-show方法的強引用self,並在-dismissWithClickedButtonIndex:animated:釋放此引用(在那裏你看到[self autorelease]註釋掉)。

你可以用一個簡單的實例變量做到這一點:

id _selfReference; 

分配self_selfReference-show

- (void)show 
{ 
    _selfReference = self; 
    ... 

,然後在-dismissWithClickedButtonIndex:animated:在這兩個地方,你看到設置_selfReference爲零[self autorelease]註釋掉了。

+0

這是正確的,它已轉換成ARC之前工作 – vichevstefan

1

將您的alert對象指定爲超出當前函數的某處。一個簡單的可能性就是把它變成一個實例變量。如果這不切合實際,請創建一個您分配/ init的實例NSMutableArray *retainedItems;,並將其填入。

+0

你的回答似乎是合理的,我想出了將它聲明爲類的強屬性,這不是理想的方法來解決這個問題,但無論如何,bug已經消失 – vichevstefan

+0

當然,記得設置一旦你完成了它,屬性就會變爲'nil',所以對象可以被清理。 – mah

1

看起來像該項目中的設計缺陷。該班級名稱很差BlockAlertView,因爲它實際上並不是UIView的子類。如果它是一個視圖並且它被添加到視圖層次結構中,那麼視圖層次結構將確保它在被查看時保持活動。由於它是視圖保持活動狀態,但創建視圖BlockAlertView的對象不會被任何東西佔用,並且在調用動作時BlockAlertView已過時。

這將需要你保持一個strong ivar左右引用這個「控制器」對象,這將是明智的nil出於完成塊伊瓦爾。

BlockAlertView *alertController = [BlockAlertView alertWithTitle:title message:message]; { 
    [alertController setCancelButtonWithTitle:NSLocalizedString(@"No", @"No Button") block:nil]; 

    __weak __typeof(self) weakSelf = self; 
    [alertController addButtonWithTitle:NSLocalizedString(@"Yes", @"Yes Button") block:^{ 
    //Do Something 
    weakSelf.alertController = nil; 
    }]; 

    [alertController show]; 
} 

self.alertController = alertController; 
+0

感謝您的評論 – vichevstefan