GameCenter的奇怪例外

Wei*_*ung 7 game-center sprite-kit sknode ios8

我一直收到来自GA和用户的崩溃报告...但是我不能通过ios7和ios8测试iphone5,5s,6来重现这个例外.当应用程序进入后台时,此问题无处可去.奇怪的是游戏中心会调用spritekit来显示成就横幅?

有没有人有同样的问题?

Last Exception Backtrace:
0   CoreFoundation                  0x23c99e3f __exceptionPreprocess + 127
1   libobjc.A.dylib                 0x31371c8b objc_exception_throw + 38
2   CoreFoundation                  0x23c9f189 -[NSObject(NSObject) doesNotRecognizeSelector:] + 188
3   CoreFoundation                  0x23c9d0a7 ___forwarding___ + 714
4   CoreFoundation                  0x23bcf208 _CF_forwarding_prep_0 + 24
5   SpriteKit                       0x26fe9689 -[SKNode isEqual:] + 164
6   Foundation                      0x248ec9ff +[NSObject(NSDelayedPerforming) cancelPreviousPerformRequestsWithTarget:] + 358
7   GameCenterFoundation            0x2a945873 -[GKPlayer postChangeNotification] + 38
8   GameCenterFoundation            0x2a958d21 __52-[GKDaemonProxy setLocalPlayer:authenticated:reply:]_block_invoke + 848
9   libdispatch.dylib               0x318d18cb _dispatch_call_block_and_release + 10
10  libdispatch.dylib               0x318d18b7 _dispatch_client_callout + 22
11  libdispatch.dylib               0x318d50bf _dispatch_main_queue_callback_4CF + 722
12  CoreFoundation                  0x23c5fbe9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
13  CoreFoundation                  0x23c5e2e9 __CFRunLoopRun + 1512
14  CoreFoundation                  0x23bac621 CFRunLoopRunSpecific + 476
15  CoreFoundation                  0x23bac433 CFRunLoopRunInMode + 106
16  GraphicsServices                0x2af1b0a9 GSEventRunModal + 136
17  UIKit                           0x27197359 UIApplicationMain + 1440
18  MyAppName                       0x001b4f27 main (main.m:16)
19  libdyld.dylib                   0x318f1aaf start + 2
Run Code Online (Sandbox Code Playgroud)

iOS8 GKLocalPlayerInternal无法识别的选择器上的类似崩溃问题

我尝试了使用SKNode和GKPlayer的测试

SKNode* node = [SKNode node];
GKPlayer* player = [GKLocalPlayer localPlayer];
[node isEqual:player];
Run Code Online (Sandbox Code Playgroud)

它会导致以下异常与上面的结果相同,这意味着系统将SKNode与[GKPlayer postChangeNotification]进行比较....这真的很奇怪.

-[GKLocalPlayerInternal name]: unrecognized selector sent to instance 0x1b6e3f80
Run Code Online (Sandbox Code Playgroud)

小智 6

我和SKNode isEqual有类似的callstack.这只发生在IOS 8.1上.有不断的崩溃,但在不同的情况下... - [GADSlot名称]:无法识别的选择器发送到实例

我认为调用此方法时会触发整个事件.+ [NSObject(NSDelayedPerforming)cancelPreviousPerformRequestsWithTarget:]

我无法解释为什么这会调用[SKNode isEqual](可能有一些东西要取消),但对我来说它会导致崩溃.我对这个问题进行了更多的调查,结果发现这是在调用我的SKScene isEqual.SKScene isEqual:方法未正确实现(我向苹果报告了一个错误).另外SKSpriteNode对我没有尝试过的SKNode的其余部分也有同样的问题,但很可能也有同样的问题.

在我的情况下,我将此修复程序添加到我的子类SKScene对象.当然它不会全局修复所有SKNode isEqual,但解决了我的问题.

   - (BOOL)isEqual:(id)other {

        if (![other isMemberOfClass:[SKScene class]]) {
            return false;
        }
        return [super isEqual:other];
    } 
Run Code Online (Sandbox Code Playgroud)


nac*_*oss 2

如果正如您所说,您可以通过简单地将 SKNode 与任何 GKLocalPlayer 进行比较来复制崩溃,那么这似乎是 SpriteKit 中的一个错误,因为对任何对象执行相等性检查不应导致崩溃。

如果您有耐力,您可以对应用程序中的所有 SKNode 进行子类化并自己实现isEqualhash方法。这应该避免对未实现该选择器的对象进行错误的名称比较检查。

我还建议您将此作为错误报告给 Apple。

这个问题似乎表明苹果确实在 iOS8 中更新了 SKNode 相等和哈希方法,因此该错误很可能是由该更改引起的。