我有一個視圖控制器,名爲AllThingsViewController動態創建其他視圖控制器,名爲ThingViewController,並將其頂級視圖添加到UIScrollView。 (我寫的專有代碼,所以我改變類的名字,但我的代碼的結構是完全一樣的。)ObjC:ARC發佈動態創建視圖控制器太早
下面是其的loadView方法包括:
NSArray *things = [[ThingDataController shared] getThings];
if ([things count] == 0) {
// code in this block is not relevant as it's not being executed...
} else {
for(unsigned int i = 0; i < [things count]; ++i) {
ThingViewController *thingViewController = [[ThingViewController alloc] init];
[thingViewController loadView];
[scrollView addSubview:thingViewController.topView];
thingViewController.topView.frame = CGRectNewOrigin(thingViewController.topView.frame,
0, thingViewController.topView.frame.size.height*i);
[thingViewController displayThing:thing[i]];
}
}
ThingViewController的的loadView方法是這樣的:
- (void)loadView
{
NSArray *topLevelObjs = nil;
topLevelObjs = [[NSBundle mainBundle] loadNibNamed:@"ThingView" owner:self options:nil];
if (topLevelObjs == nil)
{
NSLog(@"Error: Could not load ThingView xib\n");
return;
}
}
當我的應用程序啓動時的一切顯示正常,直到我試圖挖掘存在於廈門國際銀行通過ThingViewController被加載,此時它崩潰,由於異常的一個按鈕: 「無法識別的選擇器發送o實例「。看起來ARC很早就釋放了我的ThingViewController實例。
看着我的代碼,我想這是因爲他們沒有被扶着任何東西,所以我創建了一個NSMutableArray在我AllThingsViewController類的實例變量,並開始正是如此添加ThingViewControllers它:
NSArray *things = [[ThingDataController shared] getThings];
if ([things count] == 0) {
// not being executed...
} else {
for(unsigned int i = 0; i < [things count]; ++i) {
ThingViewController *thingViewController = [[ThingViewController alloc] init];
[thingViewController loadView];
[scrollView addSubview:thingViewController.topView];
thingViewController.topView.frame = CGRectNewOrigin(thingViewController.topView.frame,
0, thingViewController.topView.frame.size.height*i);
[thingViewController displayThing:thing[i]];
[allThingsViewControllers addObject:thingViewController];
}
}
但是,即使將這些對象添加到數組中,它也不會改變任何內容。最後,只是爲了確認,這是ARC早期釋放它,我改變了「thingViewController」是在AllThingsViewController一個實例變量和變化:
ThingViewController *thingViewController = [[ThingViewController alloc] init];
是:
thingViewController = [[ThingViewController alloc] init];
果然,最後當我點擊它的按鈕時,可滾動列表中的項不會崩潰,但其他項會這樣做,因爲它的ThingViewController沒有被釋放。
我對ARC還比較陌生,但是在搜索一堆Google之後,我不知道如何解決這個問題。我該怎麼辦?
請顯示*完整*「無法識別的選擇器...」錯誤消息。 –
無法識別的選擇器錯誤通常不表示某些內容發佈得太早。它抱怨什麼是無法識別的選擇器? – Jumhyn
一個完全不同的對象,那麼當我點擊一個按鈕時,我的視圖控制器正試圖響應選擇器。我所做的研究表明,這是因爲視圖控制器正在被釋放,並且一個新的對象現在居住在這部分內存中。另外,每次運行它都是嘗試執行選擇器的另一種對象。此外,如果我明確地將「thingViewController」作爲一個實例變量(因此肯定有強烈的參考),它會停止對至少一個視圖控制器的崩潰,所以我很確定問題是它也被釋放早。 – GuyGizmo