Question

I need to retrieve some data from a database to display on the screen. I want to avoid the application from blocking so I display the next screen before I retrieve any data and add the data as it comes in.

This is the method that adds the info I need on-screen:

- (void)initInfo
{
    CGSize winSize = [[CCDirector sharedDirector] winSize];
    CCMenu *infoMenu;

    // get the info in seperate thread since it may block
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        infoMenu = [PlayerInfoHelper generateInfoForPlayerWithId:[PlayerManager sharedInstance].activePlayer.objectId tag:-1 sender:self];

        dispatch_async(dispatch_get_main_queue(), ^{
            if (infoMenu != nil) {
                infoMenu.position = ccp(winSize.width - kSSInfoPaddingX, winSize.height - kSSInfoPaddingY);
                [self addChild:infoMenu z:zIndex++]; // (1)
            }
        });
    });
}

The method generateInfoForPlayerWithId:tag:sender: might block, that is the reason why I put it in its own thread. I add the menu in the main thread, since it is a UI-update.

I am sure infoMenu is a correct CCMenu* object.

I am getting a EXC_BAD_ACCESS when I do not comment out the line indicated with // (1).

Was it helpful?

Solution

To run Cocos2D in a background thread you need to create a new EAGLContext. Like this:

- (void)createMySceneInBackground
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    EAGLContext *k_context = [[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1 sharegroup:[[[[CCDirector sharedDirector] openGLView] context] sharegroup]] autorelease];
    [EAGLContext setCurrentContext:k_context];

    if (infoMenu != nil) {
        infoMenu.position = ccp(winSize.width - kSSInfoPaddingX, winSize.height - kSSInfoPaddingY);
        [self addChild:infoMenu z:zIndex++]; // (1)
    }

    [pool release];
}

Good luck!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top