Iphone Can';t显示异步加载的纹理

Iphone Can';t显示异步加载的纹理,iphone,ios,objective-c,cocos2d-iphone,grand-central-dispatch,Iphone,Ios,Objective C,Cocos2d Iphone,Grand Central Dispatch,在我的游戏中,我必须在游戏期间改变场景的背景。当我为背景设置新纹理时,游戏会慢下来一会儿。为了避免这种情况,我尝试异步预加载一个纹理,然后在主线程上显示它。我就是这样做的: NSString *filename = [NSString stringWithFormat:@"res/src/level_%i/background.png", [GameLevel sharedGameLevel].currentLevelIndex + 1]; __block CCTexture2D *textur

在我的游戏中,我必须在游戏期间改变场景的背景。当我为背景设置新纹理时,游戏会慢下来一会儿。为了避免这种情况,我尝试异步预加载一个纹理,然后在主线程上显示它。我就是这样做的:

NSString *filename = [NSString stringWithFormat:@"res/src/level_%i/background.png", [GameLevel sharedGameLevel].currentLevelIndex + 1];
__block CCTexture2D *texture;

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSLog(@"FILENAME %@", filename);
    [[CCTextureCache sharedTextureCache] addImage:filename];
    NSLog(@"%@", [CCTextureCache sharedTextureCache]);

    dispatch_async(dispatch_get_main_queue(), ^{

        texture = [[CCTextureCache sharedTextureCache] textureForKey:filename];

        [spareBackground setTexture:texture];

        [dayBackground runAction:[CCSequence actions:fadeOut,[CCCallBlockN actionWithBlock:^(CCNode *node)
        {
            NSLog(@" TEXTURE %@", texture);
            [dayBackground setTexture:texture];
            CCFadeIn *fadeIn = [[[CCFadeIn alloc] initWithDuration:5] autorelease];
            [dayBackground runAction:fadeIn];
        }], nil]];      

    });
});

但是我总是收到一个空白屏幕,而不是背景,尽管纹理已成功加载,但它不是
nil
。如果在不使用gcd的情况下将纹理加载到主线程上,则此代码可以正常工作。我缺少什么?

我怀疑
CCTextureCache
不是线程安全的(作为共享对象,它需要是线程安全的,才能从另一个线程安全调用)

另一方面,Cocos2d已经提供了异步加载纹理的机制,因此您可以使用它们。这应该是签名:

[[CCTextureCache sharedTextureCache] addImageAsync:filename target:self selector:@selector(textureLoaded:)];

如果您可以用“空间”换取“时间”,即您的游戏内存占用是合理的,请在场景开始时预装这两种纹理,在游戏过程中,只需翻转纹理的可见性即可

此外,我发现加载pvr纹理而不是png纹理将运行得更快(即我想消耗更少的cpu)。您可以尝试作为第一次尝试-希望“暂停”从用户体验的角度来看是可以接受的


注:我对性能的任何评论都是基于实际设备上的实际测量和测试。这个模拟器没用。在花费任何精力进行优化之前,确保设备上存在此“暂停”。

您的所有NSLog是否都显示了预期的结果?以及
sparebackground
dayBackground
相比如何?你想干什么?这两个任务都产生了黑色纹理吗?@sergio所有的NSlog都显示了我期望看到的东西。spareBackground就在dayBackground下面。是的,两者都是blank@AndreyChernukha:好吧,在主线程所在的CPU上运行的每个任务都会降低主线程的速度。如果查看
addImageAsync
实现,您将看到它只是在一个单独的线程中加载映像(但它是以线程安全的方式执行的)。没有理由相信创建一个CGD线程会有那么大的不同(除了处理线程安全性的成本)。你必须使用addImageAsync,没有办法解决它