2010-01-20 72 views
2

如果學會了如果委託的壽命比對象短,應該從對象中刪除委託的困難方式。但是如果你沒有對象的引用,你如何做到這一點?從未引用的對象上刪除dealloc上的委託

在我的iPhone應用程序中,我有一個視圖控制器vc,它執行異步活動並顯示爲模態視圖。取消按鈕取消模態視圖。如果發生錯誤,則顯示UIAlertView alert。如果用戶點擊確定,alert和模態視圖都會消失。因此vc被設置爲 作爲alert的代表並且實施alertView:didDismissWithButtonIndex:。例如:

// UIViewController vc 
    ... 
    UIAlertView *alert = [[UIAlertView alloc] 
          initWithTitle:@"Error" 
          message:@"Something went wrong" 
          delegate:self 
          cancelButtonTitle:@"OK" 
          otherButtonTitles:nil]; 
    self.alertView = alert; // needed to unset alertView.delegate in dealloc 
    [alert show]; 
    [alert release]; 
    ... 
} 

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { 
     [self dismissModalViewControllerAnimated:YES]; 
    } 
} 

通常,警報視圖會阻止所有輸入。不幸的是,它在某些邊緣情況下沒有這樣做。 如果用戶在警報視圖出現之前觸摸取消按鈕,並在出現警報視圖後觸摸,視圖將被取消,但不取消警報。 vc被取消分配,並且如果用戶在警報上點擊「ok」,則應用程序崩潰,因爲消息已發送到已發佈的對象。

我通過將alert分配給vc屬性解決了這個問題,所以我可以設置alert.delegate在dealloc中爲零。我覺得這個解決方案不是很優雅,因爲我不需要參考警報。

有沒有更好的方法?

編輯:添加在斜體爲澄清

回答

2

儘管通常會在不變的內容上顯示警報視圖。因此,如果代表在視圖出現時處於活動狀態,那麼當它被解散時它可能還活着。如果情況並非如此,那麼您必須完成您所做的工作,並且如果您不再關心它的結果,請手動取消設置警報視圖的委託。

所以你關心的是alertview,因爲你關心它是委託方法。問題在於,當警報解除時,代表可能不適用。所以你需要邏輯,並且爲了這個邏輯,你需要保存對有問題的alert視圖的引用。

換句話說,你是對的。雖然,如果UIAlertView保留它的委託,它可能會有所幫助,但它看起來好像不會在解散時崩潰。

最後,我認爲警報視圖阻止了所有屏幕輸入?如果沒有,您可以通過在出現警報時設置vc.view.userInteractionEnabled = NO使其成爲真正的模式,並在解除警報時將其切換回去。這樣,當警報視圖啓動時,用戶不能關閉控制器。這聽起來對我來說更加健全。

+0

我嘗試設置userInteractionEnabled = NO,但在取消按鈕的觸摸停止仍在處理。我可能不得不參考警報方式。 –

1

從用戶的角度來看,當警報視圖存在,它應該要求用戶的充分重視文本。也許您可以考慮在存在警報視圖時禁用「取消」按鈕(以及任何其他可見的非警報視圖小部件),並將按鈕標題添加到執行相同任務的UIAlertView實例。這將提供更清晰的用戶界面,並應該整齊地解決你的內存問題。

0
-(void)delayedDismiss { 
    [self dismissModalViewControllerAnimated:YES]; 
} 

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { 
    [self performSelector:@selector(delayedDismiss) withObject:nil afterDelay:0.0]; 

} 
0

如果你不再關心UIAlertView的結果,你應該也可能關閉它在- (void) viewWillDisappear:(BOOL)animated

相關問題