簡體   English   中英

當Popover仍然可見時,解除了Popover,[UIPopoverController dealloc]

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM