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 移动到屏幕顶部?