崩溃 - “在枚举时修改了集合<CALayerArray: 0x645dfc0>。”

7

目标是在viewWillAppear开始时启动一个旋转图形,先加载数据再显示tableview,以便用户不会在查看表格之前感到延迟。即窗口加入了UIActivityIndicatorView,我只想设置alpha来隐藏/显示它。

当启动线程以确保在viewWillAppear中显示“旋转齿轮”ImageView(tag=333)之前,加载/计算一些东西时,我遇到了这个奇怪的错误。

我不在每次调用[appdel addGearz]和[appdel removeGearz]时都遇到这个错误,它会发生在这两个操作中,并且是随机的。它可能发生在2个viewWillAppears之后,也可能在15个之后。如果我注释掉设置alpha的那行代码,一切都正常。

一个典型的viewWillAppear大致如下:

[super viewWillappear];
self.title=@"Products listing"; //and other simple things
[appdel addGearz];
[self getProducts];
[self getThumbnails];
[myTableView reloadData]; //in case view already loaded and coming back from subview and data changed

以下是代码,如果不注释掉.alpha行的话就会崩溃

-(void)addGearz {
    [NSThread detachNewThreadSelector:@selector(gearzOn) toTarget:self withObject:nil];
}

-(void)removeGearz {
    [NSThread detachNewThreadSelector:@selector(gearzOff) toTarget:self withObject:nil];
}

- (void)gearzOn {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [window viewWithTag:333].alpha=1.0;
        //
        //  [[window viewWithTag:333] setNeedsDisplay];
    [pool drain];
}

- (void) gearzOff {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [window viewWithTag:333].alpha=0.0;
        //
        //  [[window viewWithTag:333] setNeedsDisplay];
    [pool drain];
}

我使用了别人的代码,你能看出任何明显的问题吗?我肯定可以在一个线程中改变UIView的alpha值,需要将alpha更改“嵌入”到一些“停止枚举当我更改这个”的代码中吗?
通过将alpha更改行移到池分配之前或[pool drain]之后,我使它不崩溃了,但是然后我会收到很多“没有放置池的自动释放 - 只是泄漏”的消息。
显然,有些关于这个线程代码的东西我不理解。
1个回答

8

您不应该尝试在单独的线程上修改用户界面(UI)。UI只能在主线程上进行操作。

您应该使用performSelectorOnMainThread:withObject:waitUntilDone:而不是分离新线程。这将确保该方法将在正确的线程上调用。


[self performSelectorOnMainThread:@selector(gearzOn) withObject:nil waitUntilDone:YES]; 不会立即更新可见性,这正是整个想法 - 因为在视图推送之前,viewWillAppear将完成所有加载,用户应该意识到某些事情正在发生。 - Henrik Erlandsson
没有出现 [window setNeedsDisplay];。不过使用 alpha UIAnimation 可以解决问题。(快速淡入淡出。)有什么想法为什么这样可以工作,但是设置 alpha 并请求窗口更新却不行?我会将您的答案标记为正确,它解决了我的问题。谢谢! - Henrik Erlandsson
我猜这可能与图层的显示队列以及处理动画的方式有关。知道UIAnimation解决了问题真是太好了。 - Laurent Etiemble

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接