iOS7上的UIAlertView崩溃私有方法

Posted

技术标签:

【中文标题】iOS7上的UIAlertView崩溃私有方法【英文标题】:UIAlertView crash private method on iOS7 【发布时间】:2014-02-19 10:41:24 【问题描述】:

堆栈如下,如何修复这个崩溃? 只有ios7才有,为什么栈里还有uitableview?

0 libobjc.A.dylib objc_msgSend + 5
1 UIKit -[UIAlertView(Private) modalItem:shouldDismissForButtonAtIndex:] + 62
2 UIKit -[_UIModalItemsCoordinator _notifyDelegateModalItem:tappedButtonAtIndex:] + 94
3 UIKit -[_UIModalItemAlertContentView tableView:didSelectRowAtIndexPath:] + 894
4 UIKit -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1078
5 UIKit -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 214
6 UIKit _applyBlockToCFArrayCopiedToStack + 316
7 UIKit _afterCACommitHandler + 430
8 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 20

- (id)initWithIdentifier:(LTAlertMsgIdentifier)alertIdentifier
                delegate:(id /*<UIAlertViewDelegate>*/)delegate
       cancelButtonTitle:(NSString *)cancelButtonTitle
       otherButtonTitles:(NSString *)otherButtonTitles, ... 

    LTAlertMsgManager *sharedAlertMsgMgr = [LTAlertMsgManager shareAlertManageInstance];

    NSString *strMsg = [sharedAlertMsgMgr getLTAlertMsgByAlertID:alertIdentifier];
    if ([NSString isBlankString:strMsg])
        // alert is invalid, if alert message is empty
        return nil;
    

    NSString *strTitle = [sharedAlertMsgMgr getLTAlertTitleByAlertID:alertIdentifier];
    if (self = [super initWithTitle:([NSString isBlankString:strTitle] ? nil : strTitle)
                            message:strMsg
                           delegate:delegate
                  cancelButtonTitle:cancelButtonTitle
                  otherButtonTitles:nil])
        va_list args;
        va_start(args, otherButtonTitles);
        for (NSString *arg = otherButtonTitles; arg != nil; arg = va_arg(args, NSString*))
        
            [self addButtonWithTitle:arg];
        
        va_end(args);
    

    NSLog(@"cancel button index - %d", self.cancelButtonIndex);
    return self;


【问题讨论】:

请告诉我们 didSelectRowAtIndexPath: 描述警报视图。崩溃时你在做什么。 UIAlertView 不适用于子类化。 形成参考 UIAlertView 类旨在按原样使用,不支持子类化。此类的视图层次结构是私有的,不得修改。 @vikingosegundo 是的,但是如果您不更改视图层次结构,则子类化通常会起作用。该错误不是由子类化引起的。 【参考方案1】:

UIAlertView 中的按钮是使用UITableView 实现的。这就是为什么点击按钮会触发tableView:didSelectRowAtIndexPath

导致此类错误的典型问题是:

    主线程中未显示警报 委托已解除分配(确保警报委托在警报的整个生命周期内都保留在某处)。

【讨论】:

所有堆栈如下,我无法重现此问题。所以,我无法追踪和解决这个问题。只查看警报相关代码?谢谢! @user3327566 您添加的代码是好的。更重要的是警报的显示方式及其代表。【参考方案2】:

见iOS 7 bug or my bug in UIAlertView

UIAlertView 委托是 @property(nonatomic, assign) id delegate,所以当委托被释放时确保alertView.delegate = nil

【讨论】:

以上是关于iOS7上的UIAlertView崩溃私有方法的主要内容,如果未能解决你的问题,请参考以下文章

UIAlertView 在未记录的方法上崩溃

在带有 Xamarin.iOS 的 iOS 7 上的 ViewDidAppear 方法中显示阻止的 UIAlertView 不起作用

关于 iOS7 中的 AlertView App Crash

iOS 7 的 UIAlertView/UIAlertController 兼容性

如何在 iOS7 中将 UIDatePicker 添加到 UIALertView

在 iOS7 中显示之后/期间更新 UIAlertView 消息