2014-09-11 57 views
12

UIPopoverController中的setContentViewController方法似乎導致iOS 8中的應用崩潰。只是想知道是否有其他人在iOS 8中也面臨這個問題。這在iOS 7中沒有任何問題。popover中的setContentViewController方法iOS8導致應用崩潰

在異常指出錯誤似乎是誤導,因爲它指出呈現酥料餅

- (void)buttonPressed { 

UIViewController *tableViewController = [UIViewController new]; 

if(_popover == nil){ 

    _popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController]; 

    [_popover presentPopoverFromRect:CGRectMake(self.textField.frame.size.width/2, self.textField.frame.size.height/1, 1, 1) inView:self.textField permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES]; 
}else{ 
    [_popover setContentViewController:tableViewController]; 
}  

}

這裏後,該setContentViewController應該被稱爲是堆棧跟蹤從崩潰,

2014-09-11 16:48:39.904 iOS 8 Rotation[3969:67869] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIPopoverController setContentViewController:animated:] can only be called after the popover has been presented.' 
*** First throw call stack: 
(
    0 CoreFoundation      0x01c79df6 __exceptionPreprocess + 182 
    1 libobjc.A.dylib      0x01903a97 objc_exception_throw + 44 
    2 CoreFoundation      0x01c79d1d +[NSException raise:format:] + 141 
    3 UIKit        0x00b1946f -[UIPopoverPresentationController _setContentViewController:animated:] + 89 
    4 UIKit        0x009bb1b4 -[UIPopoverController setContentViewController:animated:] + 155 
    5 UIKit        0x009bb114 -[UIPopoverController setContentViewController:] + 48 
    6 iOS 8 Rotation      0x00046ca5 -[MianViewController buttonPressed] + 933 
    7 libobjc.A.dylib      0x019197cd -[NSObject performSelector:withObject:withObject:] + 84 
    8 UIKit        0x002ef79d -[UIApplication sendAction:to:from:forEvent:] + 99 
    9 UIKit        0x002ef72f -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64 
    10 UIKit        0x00422a16 -[UIControl sendAction:to:forEvent:] + 69 
    11 UIKit        0x00422e33 -[UIControl _sendActionsForEvents:withEvent:] + 598 
    12 UIKit        0x0042209d -[UIControl touchesEnded:withEvent:] + 660 
    13 UIKit        0x0033faba -[UIWindow _sendTouchesForEvent:] + 874 
    14 UIKit        0x00340595 -[UIWindow sendEvent:] + 791 
    15 UIKit        0x00305aa9 -[UIApplication sendEvent:] + 242 
    16 UIKit        0x003158de _UIApplicationHandleEventFromQueueEvent + 20690 
    17 UIKit        0x002ea079 _UIApplicationHandleEventQueue + 2206 
    18 CoreFoundation      0x01b9d7bf __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15 
    19 CoreFoundation      0x01b932cd __CFRunLoopDoSources0 + 253 
    20 CoreFoundation      0x01b92828 __CFRunLoopRun + 952 
    21 CoreFoundation      0x01b921ab CFRunLoopRunSpecific + 443 
    22 CoreFoundation      0x01b91fdb CFRunLoopRunInMode + 123 
    23 GraphicsServices     0x040cc24f GSEventRunModal + 192 
    24 GraphicsServices     0x040cc08c GSEventRun + 104 
    25 UIKit        0x002ede16 UIApplicationMain + 1526 
    26 iOS 8 Rotation      0x0004774d main + 141 
    27 libdyld.dylib      0x0224cac9 start + 1 
    28 ???         0x00000001 0x0 + 1 
) 
libc++abi.dylib: terminating with uncaught exception of type NSException 
+0

**總是**調用初始化程序! 'UIViewController * tableViewController = [UIViewController alloc];'是錯誤的,它必須是[[UIViewController alloc] init]或[[UIViewController alloc] initWithNibName:@「SomeNib​​Name」bundle:nil]'。但是由於通用的空視圖控制器是無用的,所以你想要實例化一個自定義的視圖控制器子類。 – DarkDust 2014-09-12 07:12:00

+0

同意,更改爲[UIViewController新] – Padmika 2014-09-13 13:09:39

+0

相同。每次我必須展示它時,我都不會重新創建popover,所以我只是介紹它。但它會導致隨機崩潰。我真的在修復...怎麼辦 – 2014-09-17 06:34:30

回答

4

我正好遇到同樣的錯誤的iOS 8下測試我們的應用程序在我們的例子中,我把面值的錯誤信息,並改變了我們在幾個地方有一個模式。

我們不得不改變的模式是: (1)在我們視圖控制器的init中,實例化一個popover控制器實例。 (2)在某些事件中,將popover控制器的contentViewController屬性設置爲所需的vc。 (3)在popover控制器上調用presentPopoverFromRect

並且我們簡單地改變步驟(2)來重新實例化具有所需內容vc作爲init參數的popover控制器,並停止設置contentViewController屬性(因爲我們總是在呈現popover之前進行)。

0

我有同樣的問題,這是什麼修復了我。

嘗試這個

- (void)buttonPressed{ 

    UIViewController *tableViewController = [UIViewController new]; 

    //Check if the popover is nil or not visible 
    if(_popover == nil || _popover.popoverVisible == false){ 

    _popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController]; 

    [_popover presentPopoverFromRect:CGRectMake(self.textField.frame.size.width/2, self.textField.frame.size.height/1, 1, 1) inView:self.textField permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES]; 
    }else{ 
    [_popover setContentViewController:tableViewController]; 
    } 
} 
+0

這種方法不適用於ios8 – Emmy 2014-09-25 06:58:35

3

我正經歷着同樣的問題終於解決了這個問題。

我有兩個按鈕,每個都顯示它自己的彈出窗口。我正在重複使用相同的UIPopoverController來顯示它們。第一次點擊工作正常,但如果你點擊另一個應用程序崩潰。

我解決它的方法是創建每次點擊一個新的UIPopoverController:

importImagePickerControlPopoverController=[[UIPopoverController alloc] initWithContentViewController:pickerController]; 
[importImagePickerControlPopoverController setDelegate:self]; 

switch(pickerType) 
{ 
    case UIImagePickerControllerSourceTypePhotoLibrary: 
    case UIImagePickerControllerSourceTypeSavedPhotosAlbum: 
     [importImagePickerControlPopoverController setPopoverContentSize:CGSizeMake(320, 300) animated:YES]; 
     break; 
    case UIImagePickerControllerSourceTypeCamera: 
     [importImagePickerControlPopoverController setPopoverContentSize:CGSizeMake(640, 640) animated:YES]; 
     break; 
} 
[importImagePickerControlPopoverController setContentViewController:pickerController]; 
0

這兩種方法添加到您的UIWebView主類。 在你的webview interface.h類中添加<UIPopoverPresentationControllerDelegate>。 定義。

@property (strong, nonatomic) UIPopoverPresentationController *pop; 

然後

@synthesize pop; 

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    // Assuming you've hooked this all up in a Storyboard with a popover presentation style 
    if ([segue.identifier isEqualToString:@"showPopover"]) { 
     UINavigationController *destNav = segue.destinationViewController; 
     pop = destNav.viewControllers.firstObject; 

     // This is the important part 
     UIPopoverPresentationController *popPC = destNav.popoverPresentationController; 
     popPC.delegate = self; 
    } 
} 
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller { 
    return UIModalPresentationNone; 
} 
2

類似於@ user3495742溶液:重新分配一個視圖控制器到現有的酥料餅時

-(void)testAndSetPopoverWithVc:(UIViewController*)vc { 
    if (popover4Menu) { 
     if ([popover4Menu isPopoverVisible]) { 
      [popover4Menu setContentViewController:vc animated:YES]; 
      return; 
     } else { 
      popover4Menu=nil; 
     } 
    }; 
    popover4Menu=[[UIPopoverController alloc] initWithContentViewController:vc]; 
    popover4Menu.delegate=self; 
} 

問題上升。 分配新內容視圖控制器之前的自由和realloc彈出窗口:這對我來說是固定的。

+2

ciao喬治,這行popover4Menu =零會導致內存泄漏/懸空指針。你可以通過填充合成屬性來實現相同的效果,該屬性將保留計數設置爲零,並正確釋放彈出窗口。 – johndpope 2014-12-01 02:01:27

+0

感謝@johnpope,我投這個提示。在我的實現中,popover4Menu是一個類私有變量,而不是一個屬性,所以我認爲將它分配給nil讓ARC管理deallocation correclty,但我還沒有深入討論它。 – 2014-12-02 15:14:52

+0

您可以通過繼承popover來查看 - 然後重寫dealloc方法(不調用super dealloc)並在那裏設置一個斷點。當你清除變量時它應該變得清晰 - 它不會正確地釋放。設置self.property = nil將正確釋放該實例。 – johndpope 2014-12-03 02:40:54

0

你已經擁有的內容視圖控制器集:

_popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController]; 
                     ↑ 
                     Here 

那麼,爲什麼不只是刪除線?:

[_popover setContentViewController:tableViewController]; 

這應該工作。

0

如果在調用[_popover setContentViewController:tableViewController];時彈出窗口不可見,則應用程序將崩潰。

因爲在屏幕上可見彈出窗口時應調用此方法。

確保你的酥料餅是可見的,

if(_popover != nil && [_popover isPopoverVisible] == YES) 
{ 
    [_popover setContentViewController:tableViewController]; 
}else 
{ 
     //create new popover object if _popover is nil or present it 
} 
0
[self.popover dismissPopoverAnimated:YES]; //in case it's already showing. 
    self.popover = nil; // N.B. this is not the same as popover = nil. 
    self.popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController]; 
    [self.popover presentPopoverFromRect:CGRectMake(self.textField.frame.size.width/
    2, self.textField.frame.size.height/1, 1, 1) inView:self.textField 
    permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES]; 
0

你並不需要創建UIPopoverController既不是你首先提出UIPopoverViewController設置新contentViewController財產後的新實例。(這取決於你如何解僱你的popoverController)

但是contentViewController不能在popoverController演示文稿之前進行更改。

要解決方法檢查popoverController.contentViewController屬性。如果它是,請設置conntentViewController,否則只顯示彈出窗口。

如果你想改變contentViewController做演講後:使用setContentViewController:動畫:方法。 請在調用此方法之前檢查popoverController.isPopoverVisible