UIActionSheet bad access, UIPresentationController

2019-05-29 08:56发布

问题:

Testing an app in iOS 8, ActionSheet keeps crashing with bad access. (Xcode 6 beta 2, iOS 8 simulator)

There is a related post here: UIActionSheet crash in iOS8beta

Instruments do catch a zombie related to UIPresentationController. I'm not sure I'm reading it correctly, but it seems that retain count drops from 6 to -1.

Here's the full log:

Event Type  ∆ RefCt RefCt   Timestamp   Responsible Library Responsible Caller
0   Malloc  +1  1   00:14.487.023   UIKit   UINibDecoderDecodeObjectForValue
1   Retain  +1  2   00:14.493.979   UIKit   -[UIRuntimeConnection initWithCoder:]
2   Retain  +1  3   00:14.494.009   UIKit   -[UIRuntimeConnection initWithCoder:]
3   Retain  +1  4   00:14.494.069   UIKit   UINibDecoderDecodeObjectForValue
4   Retain  +1  5   00:14.494.089   UIKit   UINibDecoderDecodeObjectForValue
5   Retain  +1  6   00:14.494.190   Foundation  _NSSetUsingKeyValueSetter
6   Retain  +1  7   00:14.494.257   UIKit   -[UINib instantiateWithOwner:options:]
7   Release -1  6   00:14.494.395   UIKit   -[UIRuntimeConnection dealloc]
8   Release -1  5   00:14.494.414   UIKit   -[UIRuntimeConnection dealloc]
    Release (2) -2      00:14.494.435   UIKit   -[UINibDecoder finishDecoding]
10  Release -1  3   00:14.494.458   UIKit   -[UINibDecoder finishDecoding]
12  Retain  +1  3   00:14.496.105   Vit Calc    -[RBCViewController actionSheet:clickedButtonAtIndex:]
    Retain/Release (2)          00:14.496.275   UIKit   -[_UIFullscreenPresentationController _setPresentedViewController:]
14  Retain  +1  5   00:14.510.866   UIKit   -[UIViewController setChildModalViewController:]
15  Retain  +1  6   00:14.510.886   UIKit   -[UIApplication _addViewControllerForLockingStatusBarTintColor:]
    Retain/Release (2)          00:14.511.042   UIKit   -[UIPresentationController runTransitionForCurrentState]
17  Retain  +1  8   00:14.511.112   libsystem_sim_blocks.dylib  _Block_object_assign
18  Retain  +1  9   00:14.511.135   libsystem_sim_blocks.dylib  _Block_object_assign
19  Release -1  8   00:14.511.152   UIKit   -[UIActionSheet _indexTapped:]
20  Release -1  7   00:14.514.081   GraphicsServices    GSEventRunModal
21  Release -1  6   00:14.514.098   UIKit   -[UIStoryboardScene dealloc]
22  Retain  +1  7   00:14.556.304   UIKit   -[UIPeripheralHost(UIKitInternal) _beginPinningInputViewsOnBehalfOfResponder:]
23  Retain  +1  8   00:14.564.411   UIKit   -[UIViewController _setPresentedStatusBarViewController:]
24  Release -1  7   00:14.564.660   UIKit   __destroy_helper_block_1444
25  Release -1  6   00:14.564.715   UIKit   -[UIPeripheralHost(UIKitInternal) _stopPinningInputViewsOnBehalfOfResponder:]
26  Release -1  5   00:14.564.721   UIKit   __destroy_helper_block_382
    Retain/Release (2)          00:14.581.427   Foundation  +[NSConcreteNotification newTempNotificationWithName:object:userInfo:]
    Retain/Release (2)          00:14.595.199   Foundation  +[NSConcreteNotification newTempNotificationWithName:object:userInfo:]
    Retain/Release (4)          00:14.607.299   UIKit   -[UIResponder becomeFirstResponder]
34  Retain  +1  5   00:16.014.292   UIKit   -[UIViewController _dismissViewControllerWithAnimationController:interactionController:completion:]
    Retain/Release (2)          00:16.014.324   UIKit   -[UIPresentationController runTransitionForCurrentState]
36  Retain  +1  7   00:16.014.399   libsystem_sim_blocks.dylib  _Block_object_assign
37  Release -1  6   00:16.014.430   UIKit   -[UIViewController _dismissViewControllerWithAnimationController:interactionController:completion:]
38  Release -1  5   00:16.036.310   UIKit   -[UIViewController _setPresentedStatusBarViewController:]
39  Release -1  4   00:16.036.802   UIKit   __destroy_helper_block_382
42  Retain  +1  5   00:16.546.187   UIKit   -[UIViewController _didFinishDismissTransition]
43  Retain  +1  6   00:16.546.190   UIKit   -[UIApplication _removeViewControllerForLockingStatusBarTintColor:]
44  Release -1  5   00:16.546.190   UIKit   -[UIApplication _removeViewControllerForLockingStatusBarTintColor:]
45  Release -1  4   00:16.546.191   UIKit   -[UIApplication _removeViewControllerForLockingStatusBarTintColor:]
46  Release -1  3   00:16.546.192   UIKit   -[UIViewController setChildModalViewController:]
47  Release -1  2   00:16.546.195   UIKit   -[UIViewController _didFinishDismissTransition]
50  Zombie      -1  00:18.518.590   UIKit   -[UIPresentationController runTransitionForCurrentState]

50 Zombie -1 00:18.518.590 UIKit -[UIPresentationController runTransitionForCurrentState]

Short Version (filtered)

Event Type  ∆ RefCt RefCt   Timestamp   Responsible Library Responsible Caller
    Retain/Release (2)          00:14.496.275   UIKit   -[_UIFullscreenPresentationController _setPresentedViewController:]
1   Retain  +1  7   00:14.511.042   UIKit   -[UIPresentationController runTransitionForCurrentState]
2   Retain  +1  8   00:14.564.411   UIKit   -[UIViewController _setPresentedStatusBarViewController:]
3   Retain  +1  6   00:16.014.324   UIKit   -[UIPresentationController runTransitionForCurrentState]
4   Release -1  5   00:16.036.310   UIKit   -[UIViewController _setPresentedStatusBarViewController:]
6   Zombie      -1  00:18.518.590   UIKit   -[UIPresentationController runTransitionForCurrentState]

On short version, it seems that Retain actually do the opposite:

1   Retain  +1  7   00:14.511.042   UIKit   -[UIPresentationController runTransitionForCurrentState]
3   Retain  +1  6   00:16.014.324   UIKit   -[UIPresentationController runTransitionForCurrentState]

I tried to reproduce this in a new project, but couldn't.

Also, seems to only happens when my UIActionSheet delegate is set (to self).

At this point, I just want to send Apple a more concise bug report, so I'm just trying to pinpoint the issue.


UPDATE


Can reproduce.

This happens when UIActionSheet is initialized in a separate method than the one presenting it. AND its delegate is presenting another ViewController.

For exapmle:

@implementation RBCViewController
{
    UIActionSheet *actionSheet;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self createActionSheet];
}

- (void)createActionSheet
{
    actionSheet = [[UIActionSheet alloc]init];
}

- (IBAction)showActionSheet:(UIButton *)sender {

    // Add buttons, assign delegate here

    [actionSheet showInView:self.view];
}

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    // Present another ViewContoller here.
    // This will fail with 'Bad Access' on the second time
}

回答1:

I had the same issue. The solution is to release your UIActionSheet after every use, since it will hold on the UIWindow it used to present itself (which has a unsafe_unretained pointer to the modal VC you presented).

Future readers: beware, this might no longer be true when iOS8 is released.



标签: ios8 xcode6