Pregunta

I'm out of my depth with a zombie. findMatchForRequest: is inadequate for consistent matchmaking, hence the use of [addPlayersToMatch:matchRequest:completionHandler:] where it presumably crashes:

-[__NSMallocBlock__ intValue]: unrecognized selector sent to instance
-[CFString retain]: message sent to deallocated instance // NSZombieEnabled

Below is the whole 'minimum working example' project (on Dropbox) that sooner than later crashes.

@implementation GameCenterHelper { GKMatch* _currentMatch; }
+ (GameCenterHelper *)sharedInstance {
    static GameCenterHelper* sharedHelper;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^ {
        sharedHelper = [GameCenterHelper new];
    });
    return sharedHelper;
}
- (void)authenticateLocalPlayer {
    [GKLocalPlayer localPlayer].authenticateHandler = ^(UIViewController *loginViewController, NSError *error) {
        [self findMatch];
    };
}
- (void)findMatch {
    GKMatchRequest *request = [GKMatchRequest new];
    request.minPlayers = 2;
    request.maxPlayers = 4;
    [[GKMatchmaker sharedMatchmaker] findMatchForRequest:request withCompletionHandler:^(GKMatch *match, NSError *error) {
        _currentMatch = match;
        _currentMatch.delegate = self;
    }];
}
- (void)addPlayersToMatch {
    GKMatchRequest *request = [GKMatchRequest new];
    request.minPlayers = 2;
    request.maxPlayers = 4;
    [[GKMatchmaker sharedMatchmaker] addPlayersToMatch:_currentMatch matchRequest:request completionHandler:nil];
}
- (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state {
    [self addPlayersToMatch];
}
@end

Am I missing something fundamental in memory management of blocks? The above gets called in:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[GameCenterHelper sharedInstance] authenticateLocalPlayer];
    return YES;
}

There's no error handling here, and one has to create a mockup app on iTunesConnect to experience the crash, otherwise there's no GKMatch being returned. I also made sure that bundle versions between Xcode and iTunesConnect agree, i.e. 1.0 vs 1.0.0.

Traces

Zombie caught in Instruments: enter image description here

Stack traces from Instruments for each Event Type seen above (Malloc, Release, Zombie):

Malloc at RefCt 1:

   0 libsystem_malloc.dylib malloc_zone_malloc
   1 CoreFoundation _CFRuntimeCreateInstance
   2 CoreFoundation __CFStringCreateImmutableFunnel3
   3 CoreFoundation CFStringCreateCopy
   4 CoreFoundation _CFStringCreateWithFormatAndArgumentsAux
   5 Foundation -[NSPlaceholderString initWithFormat:locale:arguments:]
   6 Foundation -[NSString initWithFormat:]
   7 GameKitServices -[GKConnectionInternal connectParticipantsWithConnectionData:withSessionInfo:]
   8 GameCenterFoundation -[GKMatch connectToPeersWithDictionaries:version:sessionToken:cdxTicket:]
   9 GameCenterFoundation __104-[GKMatchmaker matchWithRequest:currentMatch:currentPlayerIDs:serverHosted:rematchID:completionHandler:]_block_invoke_2
  10 CoreFoundation __invoking___
  11 CoreFoundation -[NSInvocation invoke]
  12 GameCenterFoundation -[NSInvocation(GKProxyHelpers) _gkInvokeOnce]
  13 GameCenterFoundation __53-[GKDaemonProxy connection:handleInvocation:isReply:]_block_invoke
  14 libdispatch.dylib _dispatch_call_block_and_release
  15 libdispatch.dylib _dispatch_client_callout
  16 libdispatch.dylib _dispatch_main_queue_callback_4CF
  17 CoreFoundation __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
  18 CoreFoundation __CFRunLoopRun
  19 CoreFoundation CFRunLoopRunSpecific
  20 CoreFoundation CFRunLoopRunInMode
  21 GraphicsServices GSEventRunModal
  22 UIKit UIApplicationMain
  23 GameCenterBug main /Volumes/Lion2/Developer/Objective-C/GameCenterBug/GameCenterBug/main.m:7
  24 libdyld.dylib start

Release at RefCt 0:

   0 CoreFoundation -[__NSCFString release]
   1 GameKitServices -[GKConnectionInternal connectParticipantsWithConnectionData:withSessionInfo:]
   2 GameCenterFoundation -[GKMatch connectToPeersWithDictionaries:version:sessionToken:cdxTicket:]
   3 GameCenterFoundation __104-[GKMatchmaker matchWithRequest:currentMatch:currentPlayerIDs:serverHosted:rematchID:completionHandler:]_block_invoke_2
   4 CoreFoundation __invoking___
   5 CoreFoundation -[NSInvocation invoke]
   6 GameCenterFoundation -[NSInvocation(GKProxyHelpers) _gkInvokeOnce]
   7 GameCenterFoundation __53-[GKDaemonProxy connection:handleInvocation:isReply:]_block_invoke
   8 libdispatch.dylib _dispatch_call_block_and_release
   9 libdispatch.dylib _dispatch_client_callout
  10 libdispatch.dylib _dispatch_main_queue_callback_4CF
  11 CoreFoundation __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
  12 CoreFoundation __CFRunLoopRun
  13 CoreFoundation CFRunLoopRunSpecific
  14 CoreFoundation CFRunLoopRunInMode
  15 GraphicsServices GSEventRunModal
  16 UIKit UIApplicationMain
  17 GameCenterBug main /Volumes/Lion2/Developer/Objective-C/GameCenterBug/GameCenterBug/main.m:7
  18 libdyld.dylib start

Zombie at RefCt -1:

   0 CoreFoundation ___forwarding___
   1 CoreFoundation _CF_forwarding_prep_0
   2 libsystem_blocks.dylib _Block_object_assign
   3 GameKitServices __copy_helper_block_355
   4 libsystem_blocks.dylib _Block_copy_internal
   5 libdispatch.dylib _dispatch_Block_copy
   6 libdispatch.dylib dispatch_group_async
   7 GameKitServices -[GKConnectionInternal connectParticipantsWithConnectionData:withSessionInfo:]
   8 GameCenterFoundation -[GKMatch connectToPeersWithDictionaries:version:sessionToken:cdxTicket:]
   9 GameCenterFoundation __104-[GKMatchmaker matchWithRequest:currentMatch:currentPlayerIDs:serverHosted:rematchID:completionHandler:]_block_invoke_2
  10 CoreFoundation __invoking___
  11 CoreFoundation -[NSInvocation invoke]
  12 GameCenterFoundation -[NSInvocation(GKProxyHelpers) _gkInvokeOnce]
  13 GameCenterFoundation __53-[GKDaemonProxy connection:handleInvocation:isReply:]_block_invoke
  14 libdispatch.dylib _dispatch_call_block_and_release
  15 libdispatch.dylib _dispatch_client_callout
  16 libdispatch.dylib _dispatch_main_queue_callback_4CF
  17 CoreFoundation __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
  18 CoreFoundation __CFRunLoopRun
  19 CoreFoundation CFRunLoopRunSpecific
  20 CoreFoundation CFRunLoopRunInMode
  21 GraphicsServices GSEventRunModal
  22 UIKit UIApplicationMain
  23 GameCenterBug main /Volumes/Lion2/Developer/Objective-C/GameCenterBug/GameCenterBug/main.m:7
  24 libdyld.dylib start

Identical, pre-ARC question (with a dubious answer): -[CFString retain]: message sent to deallocated instance 0x215076c0

Related:

¿Fue útil?

Solución

Just a few hours ago Apple said that the bug got fixed and that the fix will be in one of the next iOS versions.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top