canDisplayBannerAds = YES 导致 Sprite Kit 应用程序崩溃

Posted

技术标签:

【中文标题】canDisplayBannerAds = YES 导致 Sprite Kit 应用程序崩溃【英文标题】:canDisplayBannerAds = YES causes Sprite Kit app to crash 【发布时间】:2014-02-13 22:43:57 【问题描述】:

正在开发我的第一个游戏并尝试在其中植入广告。

我在 viewController.h 中声明了以下内容

#import <UIKit/UIKit.h>
#import <SpriteKit/SpriteKit.h>
#import <iAd/iAd.h>

@interface ViewController : UIViewController <ADBannerViewDelegate>

在我的实现文件中,我有以下内容(因为我需要横向布局而使用)

- (void)viewWillLayoutSubviews



        [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"Result"];
    [super viewWillLayoutSubviews];
    NSError *error;
    NSURL * backgroundMusicURL = [[NSBundle mainBundle] URLForResource:@"background-music-aac" withExtension:@"caf"];
    self.backgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicURL error:&error];
    self.backgroundMusicPlayer.numberOfLoops = -1;
    [self.backgroundMusicPlayer prepareToPlay];
    [self.backgroundMusicPlayer play];

    // Configure the view.

    SKView * skView = (SKView *)self.view;
    if (!skView.scene) 
      skView.showsFPS = YES;
      skView.showsNodeCount = YES;

      // Create and configure the scene.
      SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
      scene.scaleMode = SKSceneScaleModeAspectFill;

      // Present the scene.
      [skView presentScene:scene];
        self.canDisplayBannerAds = YES;

    

但是,当我运行应用程序时立即崩溃(下面的日志) - 如果我更改 self.canDisplayBannerAdds = NO;该应用程序运行良好 - 我觉得这非常简单,但我看不到它 - 有人有什么想法吗?

2014-02-13 22:40:20.605 SpriteKitSimpleGame[2812:70b] -[UIView scene]: unrecognized selector sent to instance 0xcb354c0
2014-02-13 22:40:20.608 SpriteKitSimpleGame[2812:70b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIView scene]: unrecognized selector sent to instance 0xcb354c0'
*** First throw call stack:
(
    0   CoreFoundation                      0x019fa5e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x0177d8b6 objc_exception_throw + 44
    2   CoreFoundation                      0x01a97903 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
    3   CoreFoundation                      0x019ea90b ___forwarding___ + 1019
    4   CoreFoundation                      0x019ea4ee _CF_forwarding_prep_0 + 14
    5   SpriteKitSimpleGame                 0x00008169 -[ViewController viewWillLayoutSubviews] + 729
    6   UIKit                               0x0043321a -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 278
    7   libobjc.A.dylib                     0x0178f81f -[NSObject performSelector:withObject:] + 70
    8   QuartzCore                          0x0232e2ea -[CALayer layoutSublayers] + 148
    9   QuartzCore                          0x023220d4 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
    10  QuartzCore                          0x0232e235 -[CALayer layoutIfNeeded] + 160
    11  UIKit                               0x004ee613 -[UIViewController window:setupWithInterfaceOrientation:] + 304
    12  UIKit                               0x0040d177 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] + 5212
    13  UIKit                               0x0040bd16 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 82
    14  UIKit                               0x0040bbe8 -[UIWindow _setRotatableViewOrientation:updateStatusBar:duration:force:] + 117
    15  UIKit                               0x0040bc70 -[UIWindow _setRotatableViewOrientation:duration:force:] + 67
    16  UIKit                               0x0040ad0a __57-[UIWindow _updateToInterfaceOrientation:duration:force:]_block_invoke + 120
    17  UIKit                               0x0040ac6c -[UIWindow _updateToInterfaceOrientation:duration:force:] + 400
    18  UIKit                               0x0040b9c3 -[UIWindow setAutorotates:forceUpdateInterfaceOrientation:] + 870
    19  UIKit                               0x0040efb6 -[UIWindow setDelegate:] + 449
    20  UIKit                               0x004e0737 -[UIViewController _tryBecomeRootViewControllerInWindow:] + 180
    21  UIKit                               0x00404c1c -[UIWindow addRootViewControllerViewIfPossible] + 609
    22  UIKit                               0x00404d97 -[UIWindow _setHidden:forced:] + 312
    23  UIKit                               0x0040502d -[UIWindow _orderFrontWithoutMakingKey] + 49
    24  UIKit                               0x0040f89a -[UIWindow makeKeyAndVisible] + 65
    25  UIKit                               0x003c2cd0 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1851
    26  UIKit                               0x003c73a8 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 824
    27  UIKit                               0x003db87c -[UIApplication handleEvent:withNewEvent:] + 3447
    28  UIKit                               0x003dbde9 -[UIApplication sendEvent:] + 85
    29  UIKit                               0x003c9025 _UIApplicationHandleEvent + 736
    30  GraphicsServices                    0x027b12f6 _PurpleEventCallback + 776
    31  GraphicsServices                    0x027b0e01 PurpleEventCallback + 46
    32  CoreFoundation                      0x01975d65 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
    33  CoreFoundation                      0x01975a9b __CFRunLoopDoSource1 + 523
    34  CoreFoundation                      0x019a077c __CFRunLoopRun + 2156
    35  CoreFoundation                      0x0199fac3 CFRunLoopRunSpecific + 467
    36  CoreFoundation                      0x0199f8db CFRunLoopRunInMode + 123
    37  UIKit                               0x003c6add -[UIApplication _run] + 840
    38  UIKit                               0x003c8d3b UIApplicationMain + 1225
    39  SpriteKitSimpleGame                 0x0000979d main + 141
    40  libdyld.dylib                       0x0310570d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

【问题讨论】:

听起来 viewcontroller 的视图不是 SKView 而是 UIBiew 或子类(广告视图?),它没有名为 scene 的方法 这是在标准 UiView 中,然后在设置结束时显示 SKScene。有没有办法解决这个问题? 只有 SKView 才能呈现 Sprite Kit 场景 是的 - 但我的 SKView 呈现良好(至少当我没有 candisplaybannerads 行时),是广告代码提供了我的问题 这是您得到的错误:“[UIView 场景]:无法识别的选择器已发送到实例”,这意味着您正在将“场景”选择器/消息发送到 UIView 类的对象。您在上面的代码中执行此操作的唯一位置(尽管您也可能在其他地方执行此操作)是:SKView * skView = (SKView *)self.view; if (!skView.scene) .... 验证 self.view 实际上是 SKView 类。如果不是,则错误是 self.view 不是 SKView。 【参考方案1】:

canDisplayBannerAdds 设置为YES 时,您需要在控制器上使用originalContentView 来获取视图。

尝试使用以下代码获取您的视图:

SKView * skView = self.originalContentView;

【讨论】:

这可行但会发出警告,所以只需添加(SKView*)self.originalContentView 但是 originalContentView 返回一个 UIView,而不是 SKView。

以上是关于canDisplayBannerAds = YES 导致 Sprite Kit 应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

如何在使用 canDisplayBannerAds 的 iOS7 应用程序中将 iAd 移动到屏幕顶部?

如何阻止 iAds 在 xcode 中扭曲 SKScene?

Sprite Kit 中的顶部屏幕 iAd

停止 iAd 自动布局

从 SKScene 中删除 iAd

带有 iAd 横幅的 UITableView 上的奇怪溢出