0

我尝试在 iPad(设备和模拟器)上测试 iPhone(非通用)应用程序,但出现此错误:

2013-02-09 15:25:23.907 iFormularioNew_Free[5160:c07] CRASH: *** -[__NSArrayM insertObject:atIndex:]: object cannot be nil
2013-02-09 15:25:23.910 iFormularioNew_Free[5160:c07] Stack Trace: (
    0   CoreFoundation                      0x0204d02e __exceptionPreprocess + 206
    1   libobjc.A.dylib                     0x0151ee7e objc_exception_throw + 44
    2   CoreFoundation                      0x02000b6a -[__NSArrayM insertObject:atIndex:] + 314
    3   CoreFoundation                      0x02000a20 -[__NSArrayM addObject:] + 64
    4   UIKit                               0x00545894 -[UIViewController _addChildViewController:performHierarchyCheck:notifyWillMove:] + 344
    5   UIKit                               0x00553b8c -[UIViewController(UIContainerViewControllerProtectedMethods) addChildViewController:] + 68
    6   iFormularioNew_Free                 0x0003a27c -[BannerViewController loadView] + 348
    7   UIKit                               0x00543ff8 -[UIViewController loadViewIfRequired] + 73
    8   UIKit                               0x00544232 -[UIViewController view] + 33
    9   iFormularioNew_Free                 0x0003aa81 __63-[BannerViewController bannerView:didFailToReceiveAdWithError:]_block_invoke + 49
    10  UIKit                               0x004ae067 +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:animations:start:completion:] + 506
    11  UIKit                               0x004ae276 +[UIView(UIViewAnimationWithBlocks) animateWithDuration:animations:] + 99
    12  iFormularioNew_Free                 0x0003a9fb -[BannerViewController bannerView:didFailToReceiveAdWithError:] + 283
    13  iAd                                 0x00072d23 -[ADBannerView _sanitizeAndForwardErrorToDelegate:] + 254
    14  iAd                                 0x00072991 __28-[ADBannerView setDelegate:]_block_invoke_0 + 92
    15  iAd                                 0x00072916 -[ADBannerView setDelegate:] + 266
    16  iFormularioNew_Free                 0x0003a0ae -[BannerViewController initWithContentViewController:] + 382
    17  iFormularioNew_Free                 0x0000336e -[AppDelegate application:didFinishLaunchingWithOptions:] + 4718
    18  UIKit                               0x00460157 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 266
    19  UIKit                               0x00460747 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1248
    20  UIKit                               0x0046194b -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 805
    21  UIKit                               0x00472cb5 -[UIApplication handleEvent:withNewEvent:] + 1022
    22  UIKit                               0x00473beb -[UIApplication sendEvent:] + 85
    23  UIKit                               0x00465698 _UIApplicationHandleEvent + 9874
    24  GraphicsServices                    0x0193adf9 _PurpleEventCallback + 339
    25  GraphicsServices                    0x0193aad0 PurpleEventCallback + 46
    26  CoreFoundation                      0x01fc2bf5 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
    27  CoreFoundation                      0x01fc2962 __CFRunLoopDoSource1 + 146
    28  CoreFoundation                      0x01ff3bb6 __CFRunLoopRun + 2118
    29  CoreFoundation                      0x01ff2f44 CFRunLoopRunSpecific + 276
    30  CoreFoundation                      0x01ff2e1b CFRunLoopRunInMode + 123
    31  UIKit                               0x0046117a -[UIApplication _run] + 774
    32  UIKit                               0x00462ffc UIApplicationMain + 1211
    33  iFormularioNew_Free                 0x0000202d main + 141
    34  iFormularioNew_Free                 0x00001f55 start + 53
)
2013-02-09 15:25:23.953 iFormularioNew_Free[5160:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(0x204d012 0x151ee7e 0x2000b6a 0x2000a20 0x545894 0x553b8c 0x3a27c 0x543ff8 0x544232 0x3aa81 0x4ae067 0x4ae276 0x3a9fb 0x72d23 0x72991 0x72916 0x3a0ae 0x336e 0x460157 0x460747 0x46194b 0x472cb5 0x473beb 0x465698 0x193adf9 0x193aad0 0x1fc2bf5 0x1fc2962 0x1ff3bb6 0x1ff2f44 0x1ff2e1b 0x46117a 0x462ffc 0x202d 0x1f55)
libc++abi.dylib: terminate called throwing an exception

如果我得到 iADSuite 示例代码并且我从通用更改为 iphone 并在 ipad(设备或模拟器)上测试应用程序,我会得到相同的错误。哪里有问题?

编辑:代码:

这里崩溃:

_bannerViewController = [[BannerViewController alloc] initWithContentViewController:self.tabBarController];
self.window.rootViewController = _bannerViewController;

BannerViewController.m

NSString * const BannerViewActionWillBegin = @"BannerViewActionWillBegin";
NSString * const BannerViewActionDidFinish = @"BannerViewActionDidFinish";

@interface BannerViewController () <ADBannerViewDelegate>

@end

@implementation BannerViewController {
    ADBannerView *_bannerView;
    UIViewController *_contentController;
}

- (instancetype)initWithContentViewController:(UIViewController *)contentController
{
    self = [super init];
    if (self != nil) {
        // On iOS 6 ADBannerView introduces a new initializer, use it when available.
        if ([ADBannerView instancesRespondToSelector:@selector(initWithAdType:)]) {
            _bannerView = [[ADBannerView alloc] initWithAdType:ADAdTypeBanner];
        } else {
            _bannerView = [[ADBannerView alloc] init];
        }
        _bannerView.delegate = self;
        _contentController = contentController;
    }
    return self;
}

- (void)loadView{
    UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    [contentView addSubview:_bannerView];
    [self addChildViewController:_contentController];
    [contentView addSubview:_contentController.view];
    [_contentController didMoveToParentViewController:self];
    self.view = contentView;
}

#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return [_contentController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
#endif

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
    return [_contentController preferredInterfaceOrientationForPresentation];
}

- (NSUInteger)supportedInterfaceOrientations{
    return [_contentController supportedInterfaceOrientations];
}

- (void)viewDidLayoutSubviews{
    CGRect contentFrame = self.view.bounds, bannerFrame = CGRectZero;
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
    // If configured to support iOS <6.0, then we need to set the currentContentSizeIdentifier in order to resize the banner properly.
    // This continues to work on iOS 6.0, so we won't need to do anything further to resize the banner.
    if (contentFrame.size.width < contentFrame.size.height) {
        _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
    } else {
        _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape;
    }
    bannerFrame = _bannerView.frame;
#else
    // If configured to support iOS >= 6.0 only, then we want to avoid currentContentSizeIdentifier as it is deprecated.
    // Fortunately all we need to do is ask the banner for a size that fits into the layout area we are using.
    // At this point in this method contentFrame=self.view.bounds, so we'll use that size for the layout.
    bannerFrame.size = [_bannerView sizeThatFits:contentFrame.size];
#endif

    if (_bannerView.bannerLoaded) {
        contentFrame.size.height -= bannerFrame.size.height;
        bannerFrame.origin.y = contentFrame.size.height;
    } else {
        bannerFrame.origin.y = contentFrame.size.height;
    }
    _contentController.view.frame = contentFrame;
    _bannerView.frame = bannerFrame;
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner{
    [[NSNotificationCenter defaultCenter] postNotificationName:BannerViewActionWillBegin object:self];

    [UIView animateWithDuration:0.25 animations:^{
        [self.view setNeedsLayout];
        [self.view layoutIfNeeded];
    }];
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
    [[NSNotificationCenter defaultCenter] postNotificationName:BannerViewActionDidFinish object:self];

    [UIView animateWithDuration:0.25 animations:^{
        [self.view setNeedsLayout];
        [self.view layoutIfNeeded];
    }];
}
- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave {
    return YES;
}
- (void)bannerViewActionDidFinish:(ADBannerView *)banner{}
4

2 回答 2

4

我删除了我之前的答案,而是发布了这个新答案。

查看堆栈跟踪。问题是由于调用:

_bannerView.delegate = self;

这会导致一连串的调用导致loadView方法BannerViewController在仍在initWithContentViewController:执行的过程中被调用。但此时,_contentControllerivar 尚未设置。

鉴于设置委托会启动广告加载并需要视图,最好的解决方案是等待并_bannerView.delegateviewDidLoad方法中设置。

另一种解决方案是将initWithContentViewController:方法中的调用重新排序为:

- (instancetype)initWithContentViewController:(UIViewController *)contentController {
    self = [super init];
    if (self != nil) {
        // This must be called before you set the delegate on _bannerView
        _contentController = contentController;

        // On iOS 6 ADBannerView introduces a new initializer, use it when available.
        if ([ADBannerView instancesRespondToSelector:@selector(initWithAdType:)]) {
            _bannerView = [[ADBannerView alloc] initWithAdType:ADAdTypeBanner];
        } else {
            _bannerView = [[ADBannerView alloc] init];
        }
        _bannerView.delegate = self;
    }

    return self;
}

另一个解决方案是摆脱loadView实现并将所有代码(减去创建内容视图)放在viewDidLoad.

于 2013-02-10T01:14:14.747 回答
2

如果没有代码,我无法指出确切的问题出在哪里,但错误很明显:您正在尝试将“nil”对象插入 NSMutableArray,但此类不允许!

NS 数组和字典不能将 nil 存储为值:如果你这样做,应用程序会引发异常(如果你不处理它,应用程序会崩溃)。

编辑:从调用堆栈中,您会看到错误在:

6   iFormularioNew_Free                 0x0003a27c -[BannerViewController loadView] + 348

所以你应该看看 loadView 方法,在这一行:

[self addChildViewController:_contentController];

我确定当它崩溃时 _contentController 为零(addChildViewController 将控制器添加到父级拥有的子控制器数组中)。我留给你去发现为什么它是 nil ;)

于 2013-02-09T15:06:32.657 回答