游戏中心出现异常的问题

7
我经常从GA和用户那里收到这个崩溃报告...但是我无法在测试iPhone5、5s、6的iOS7和iOS8时再现此异常。这个问题在应用程序进入后台时出现了。奇怪的是,Gamecenter会调用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

iOS8 GKLocalPlayerInternal Unrecognized Selector问题上出现了类似的崩溃问题。

我尝试使用SKNode和GKPlayer进行测试。

SKNode* node = [SKNode node];
GKPlayer* player = [GKLocalPlayer localPlayer];
[node isEqual:player];

与上面的结果一样,它会引起以下异常,这意味着系统将SKNode与[GKPlayer postChangeNotification]进行比较......真的很奇怪。
-[GKLocalPlayerInternal name]: unrecognized selector sent to instance 0x1b6e3f80
3个回答

6

我曾经遇到和SKNode isEqual类似的调用堆栈。这种情况只在IOS 8.1上发生。一直出现崩溃,但是在不同的场景下... -[GADSlot name]: unrecognized selector sent to instance

我认为整个问题都是在调用此方法时触发的。 +[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];
    } 

你的回答真的帮了我很大的忙,我已经很长时间在寻找这个问题的解决方案了。非常感谢! - Oscar
非常感谢!!!在我所有的SKScene子类中重写isEqual完全解决了令人生畏的"[GKLocalPlayerInternal name]: unrecognized selector"错误。 - Norman G
你们好!往前看,我也注意到SKSpriteNode也有同样的问题,虽然没有尝试过,但我认为SKNode也有这个问题。因此,它可能会覆盖SKScene的isEquals工作,但要密切关注并进行深入测试。如果可能的话,也可以值得为SKNode子类进行重写(如果您对其具有控制权)。特别是在我的一个SKSpriteNode子类中,我不得不进行重写,因为我正在使用[self performSelector:@selector(..)。 - gili

2
如果按照你的说法,通过将SKNode与任何GKLocalPlayer进行比较就可以复制崩溃的问题,那么似乎这是SpriteKit中的一个错误,因为对任何对象执行等式检查不应导致崩溃。
如果你有精力,你可以子类化你的应用程序中的所有SKNode,并自己实现isEqualhash方法。这应该避免在不实现该选择器的对象上进行错误的名称比较检查。
我也建议你向苹果报告这个错误。 这个问题似乎表明,苹果确实在iOS8中更新了SKNode的相等性和哈希方法,所以这个错误很可能是由于这个变化引起的。

SpriteKit在iOS 8中仍然存在许多漏洞,自从第一个测试版发布以来... - Bruno Philipe

0

Swift中的子类:

import SpriteKit

class Scene: SKScene {

    override func isEqual(object: AnyObject?) -> Bool {
        if object?.isKindOfClass(SKScene) == false {
            return false
        }

        return super.isEqual(object)
    }
}

申请:

class YourScene: Scene {
    // your code
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接