0

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).

mmvie
  • 2,571
  • 7
  • 24
  • 39
  • By Line 1 you mean : CGSize winSize = [[CCDirector sharedDirector] winSize]; ? – Suny Aug 03 '12 at 14:52
  • No, the line with // (1) behind it... comes down to: [self addChild:infoMenu z:zIndex++]; – mmvie Aug 03 '12 at 14:54
  • Can you debug and see if InfoMenu really has anything in it ? – Suny Aug 03 '12 at 14:55
  • As I stated in the original question, I am sure. That means I already debugged it... – mmvie Aug 03 '12 at 14:56
  • What kind of class is the (ie `UIView` subclass etc), is there code for `addChild::`? Have you tried making `infoMenu` a `strong` property? Or tried an `NSLog([infoMenu description])` to check it contains what you want it too? – Sam Clewlow Aug 03 '12 at 15:04
  • This code is inside a CCLayer. addChild comes from cocos2d. Turning infoMenu into a strong property doesn't make any difference and infoMenu contains what it should. – mmvie Aug 03 '12 at 15:10

1 Answers1

2

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!

Ricard Pérez del Campo
  • 2,387
  • 1
  • 19
  • 22