Ios8 GameCenter有个奇怪的例外

Ios8 GameCenter有个奇怪的例外,ios8,sprite-kit,game-center,sknode,Ios8,Sprite Kit,Game Center,Sknode,我一直从GA和用户那里得到这个崩溃报告。。。然而,我无法通过同时使用ios7和ios8测试iphone5、5s和6来重现这个异常。当应用程序进入后台时,这个问题就不会出现了。奇怪的是游戏中心会叫spritekit来展示成就横幅 有人有同样的问题吗 Last Exception Backtrace: 0 CoreFoundation 0x23c99e3f __exceptionPreprocess + 127 1 libobjc.A.dylib

我一直从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
类似坠机事件

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

SKNode* node = [SKNode node];
GKPlayer* player = [GKLocalPlayer localPlayer];
[node isEqual:player];
它将导致与上述结果相同的以下异常,这意味着系统将SKNode与[GKPlayer postChangeNotification]进行比较……这真的很奇怪

-[GKLocalPlayerInternal name]: unrecognized selector sent to instance 0x1b6e3f80

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

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

我还建议您将此作为bug报告给苹果


似乎表明苹果确实在iOS8中更新了SKNode equality和散列方法,所以很可能是这个错误引起的。

我与SKNode isEqual有类似的调用堆栈。这仅在IOS 8.1上发生。不断的崩溃,但在不同的情况下。。。 -[GADSlot name]:发送到实例的选择器无法识别

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

我无法解释为什么这会调用[SKNode isEqual](可能有一些东西需要取消),但对我来说,它会导致崩溃。 我在这个问题上做了更多的调查,结果发现这是在说我的SKScene是平等的。sksceneisequal:方法没有正确实现(我向苹果报告了一个bug)。另外,SKSpriteNode对于其余的SKNode也有相同的问题,我没有尝试过,但很可能有相同的问题

在我的例子中,我将此修复添加到我的子类SKScene对象中。当然,它不会在全局范围内修复所有SKNode isEqual,但解决了我的问题

   - (BOOL)isEqual:(id)other {

        if (![other isMemberOfClass:[SKScene class]]) {
            return false;
        }
        return [super isEqual:other];
    } 
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
}

SpriteKit在iOS 8中仍然是非常有缺陷的,自从第一个测试版发布以来…你用这个答案真的救了我,我一直在寻找解决这个问题的方法。谢谢!非常感谢!!!!在我所有的SKScene子类中覆盖isEqual完全解决了可怕的“[GKLocalPlayerInternal name]:无法识别的选择器”错误。欢迎你们!向前一点,我也注意到SKSpriteNode也有同样的问题,没有尝试,但我认为SKNode有问题。因此,它可以覆盖SKScene isEquals的工作,但要密切关注和深入测试。如果可能的话,对于SKNode子类也值得重写(如果您可以控制它的话)。特别地,我必须在我的一个子类SKSpriteNode中重写我使用的[self-performSelector:@selector(..)的地方。