![](/img/trans.png)
[英]UIPopovercontroller dealloc reached while popover is still visible
[英]Dismissing Popover, [UIPopoverController dealloc] reached while popover is still visible
我有一個UIPopoverController存儲在我的View Controller中的一個強屬性中。 當用戶在彈出窗口可見時旋轉iPad時,我會關閉彈出框並將我的屬性設置為nil。
if (self.popover != nil) {
[self.popover dismissPopoverAnimated:NO];
self.popover.delegate = nil;
self.popover = nil;
}
當代碼變為self.popover = nil時,ARC會嘗試解除對UIPopoverController的拒絕,但它會崩潰,因為它應該仍然可見。
如果不崩潰,我該如何解雇和淘汰彈出窗口?
首先,建議檢查彈出窗口是否正在顯示,這將方便地檢查是否已分配:
if ([self.popover isPopoverVisible]) {
[self.popover dismissPopoverAnimated:NO];
}
現在,問題是,你沒有得到委托回調- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
如果你以編程方式解除- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
這樣,但你需要一個強大的popover引用,直到它不再可見。
執行此操作的方法是將屬性延遲設置為nil,直到返回主運行循環,因為當您返回主運行循環時,所有動畫都將完成,因此彈出窗口將不再可見。
您將要將設置popover的代碼移動到另一個方法:
- (void)releasePopover {
self.popover.delegate = nil;
self.popover = nil;
}
然后,在你的旋轉回調中,添加此方法以在主運行循環上觸發,我喜歡通過向主運行循環添加調用操作來執行此操作:
if ([self.popover isPopoverVisible]){
[self.popover dismissPopoverAnimated:NO];
NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(releasePopover) object:nil];
[[NSOperationQueue mainQueue] addOperation:invocationOperation];
}
最后,為了清潔起見,您可能希望從- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
回調中調用-releasePopover
。
所以,把它們放在一起:
- (void)releasePopover
{
self.popover.delegate = nil;
self.popover = nil;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if ([self.popover isPopoverVisible]){
[self.popover dismissPopoverAnimated:NO];
NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(releasePopover) object:nil];
[[NSOperationQueue mainQueue] addOperation:invocationOperation];
}
}
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
[self releasePopover];
}
說了這么多,除非有充分的理由,否則你可能只想讓popover重新使用,只有當你得到低內存警告時和/或你的視圖被卸載時才設置為nil,正如Chris Loonam提到的那樣回答
如果您確實認為有必要這樣做,請嘗試在viewDidUnload中將其取消。 由於ARC自動釋放對象,我不確定這是否真的有必要。
站在西蒙回答的肩膀上,這是我對崩潰的解決方法:
// set to nil on main queue to prevent "dealloc'd while still visible" exception
dispatch_async(dispatch_get_main_queue(), ^{
self.popover = nil;
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.