崩溃 - “集合 <CALayerArray: 0x645dfc0> 在枚举时发生了变异。”

Posted

技术标签:

【中文标题】崩溃 - “集合 <CALayerArray: 0x645dfc0> 在枚举时发生了变异。”【英文标题】:Crash - "Collection <CALayerArray: 0x645dfc0> was mutated while being enumerated." 【发布时间】:2011-01-21 10:08:30 【问题描述】:

目标是“在 viewWillAppear 开始时启动一个微调器图形,在显示表格视图之前加载数据”,这样用户就不会想知道为什么在看到表格之前会有延迟。 IE。 UIActivityIndi​​catorView 已添加到窗口中,我只想将 alpha 设置为隐藏/显示它。

我在启动线程以确保显示“旋转齿轮”图像视图 (tag=333) 时遇到这个奇怪的错误,然后继续加载/计算 viewWillAppear 中的内容。

我不会在每次调用 [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];

我使用了别人的代码,所以……你能看到什么明显的东西吗?当然我必须能够在线程中更改 UIViews 的 alpha 吗?我是否需要在一些“更改此代码时停止枚举”代码中“嵌入”alpha 更改?

我通过将 alpha-change-line 移动到池分配上方或 [池排水] 下方使其不会崩溃,但随后我收到了很多“自动释放而没有适当的池 - 只是泄漏”的消息。

显然,我对这个线程代码有些地方不明白。

【问题讨论】:

【参考方案1】:

您不得尝试在单独的线程上修改 UI。 UI 只能在主线程上操作。

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

【讨论】:

[self performSelectorOnMainThread:@selector(gearzOn) withObject:nil waitUntilDone:YES];不会立即更新可见性,这是​​整个想法 - 因为 viewWillAppear 将在视图被推送之前完成所有加载,用户应该知道正在发生一些事情。 没有出现 [window setNeedsDisplay];任何一个。不过,使用 alpha UIAnimation 是可行的。 (快速淡入淡出。)任何想法为什么它有效但不设置 alpha 并要求窗口更新?将您的答案标记为正确,它解决了问题。谢谢! 我猜它与图层的显示队列和动画处理方式有关。很高兴知道 UIAnimation 成功了。

以上是关于崩溃 - “集合 <CALayerArray: 0x645dfc0> 在枚举时发生了变异。”的主要内容,如果未能解决你的问题,请参考以下文章

存档崩溃中的 iOS 崩溃似乎是块

VS2013 程序崩溃了 怎么定位到造成崩溃原因的语句

如何防止 Bootstrap 崩溃的子项在崩溃崩溃时调整大小

请教如何生成程序的崩溃日志

如何获得Android的崩溃日志

HarmonyOS崩溃服务能力全新上线,帮你高效解决崩溃问题!