2013-02-09 86 views
0

我尝试测试的iPhone(不通用)的应用程序在iPad(设备和仿真器),但我得到这个错误:崩溃仅与iPad(模拟器或设备) - [__NSArrayM insertObject:atIndex:]

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

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

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

_bannerView.delegate = self; 

这导致调用链导致的BannerViewControllerloadView方法,同时仍然在initWithContentViewController:中间执行被调用。但在这一点上,伊娃尚未设定。

鉴于设置委托启动广告加载和需要查看,最好的解决方案是等待并设置viewDidLoad方法中的_bannerView.delegate

另一种解决方案是在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的开头。

+0

以这种方式应用程序不会崩溃,同时仅在_contentController = contentController;但现在的应用程序不显示横幅....我尝试了很多时间,没有什么,如果我尝试pp在iPhone模拟器上我得到的横幅! – kikko088 2013-02-10 13:16:55

+1

我发现苹果公司的这个说明:“在iPad上以兼容模式运行的iPhone应用程序不会在兼容环境中运行的部署应用程序中显示测试广告,或者在部署的应用程序中显示实时广告。所有的客户,确保你已经开发出一个支持所有可能的设备的应用程序。“这是否意味着在2x模式下iAd不起作用? – kikko088 2013-02-10 15:42:56

+0

这对我有用。 – Robert 2013-03-06 02:05:04

2

如果没有代码,其确切的问题,打好我不能指出,但错误很明显:你试图插入一个“无”对象到NSMutableArray中,但是这个类不允许它!

NS数组和字典无法将nil存储为值:如果您这样做,应用程序会产生异常(并且如果您不处理应用程序崩溃)。

编辑: 从调用堆栈,你看到的错误是:

6 iFormularioNew_Free     0x0003a27c -[BannerViewController loadView] + 348 

所以你应该看的loadView方法,在线路:

[self addChildViewController:_contentController]; 

我敢肯定,当它崩溃_contentController为零(addChildViewController将控制器添加到由父级拥有的子控制器数组)。我留给你发现为什么它为零;)

+0

该代码有点长,但错误在这里:_bannerViewController = [[BannerViewController alloc] initWithContentViewController:self.tabBarController]; self.window.rootViewController = _bannerViewController;我认为你更好地理解下载这个问题:http://developer.apple。com/library/ios /#samplecode/iAdSuite/Introduction/Intro.html,将SplitNavigationBanner仅用于iPhone,并在iPad模拟器中打开。现在我编辑我的问题 – kikko088 2013-02-09 15:19:39

+0

问题在这里,如果([ADBannerView instancesRespondToSelector:@selector(initWithAdType :)]){_bannerView = [[ADBannerView alloc] initWithAdType:ADAdTypeBanner]; }如果我评论这行应用程序不会崩溃!问题是为什么?:( – kikko088 2013-02-10 01:04:32

+0

横幅也可以在模拟器上运行(只是你没有得到一个真正的广告,只是一个“占位符”,显示你的一切都是正确的),但你必须指定你想获得的横幅类型iPhone/iPad ...),所以有时你应该什么也得不到。 – 2013-02-11 13:33:18

相关问题