2012-08-13 83 views
2

我的应用程序创建UIView的自定义子类的实例,并添加水平放置在彼此相邻的实例。当我的UIView类的新实例被创建时,我可以将它添加到UIScrollView并重置内容大小。然后我打电话给 [UIScrollView setContentOffset:(some point) animated:NO]。 这工作得很好。 问题是当我用动画调用上述方法时,即 [UIScrollView setContentOffset:(some point) animated:YES] ,应用程序崩溃。 调用堆栈看起来是这样的:如果使用动画调用setContentOffset,则UIScrollView崩溃

> #0 0x3145b870 in ___forwarding___() 
> #1 0x313b6650 in _CF_forwarding_prep_0() 
> #2 0x317d84a2 in -[UIAnimator stopAnimation:]() 
> #3 0x317d84a2 in -[UIAnimator stopAnimation:]() 
> #4 0x317d7f0e in -[UIAnimator(Static) _advance:withTimestamp:]() 
> #5 0x317d7e00 in -[UIAnimator(Static) _LCDHeartbeatCallback:]() 
> #6 0x3531d86e in CA::Display::DisplayLink::dispatch(unsigned long long, unsigned long long)() 
> #7 0x3531d7c4 in CA::Display::IOMFBDisplayLink::callback(__IOMobileFramebuffer*, 
> unsigned long long, unsigned long long, unsigned long long, void*)() 
> #8 0x33a56000 in IOMobileFramebufferVsyncNotifyFunc() 
> #9 0x36e3c60c in IODispatchCalloutFromCFMessage() 
> #10 0x31422f12 in __CFMachPortPerform() 
> #11 0x3142d522 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__() 
> #12 0x3142d4c4 in __CFRunLoopDoSource1() 
> #13 0x3142c312 in __CFRunLoopRun() 
> #14 0x313af4a4 in CFRunLoopRunSpecific() 
> #15 0x313af36c in CFRunLoopRunInMode() 
> #16 0x32888438 in GSEventRunModal() 
> #17 0x316b4cd4 in UIApplicationMain() 

当我使植物大战僵尸,应用输出产生:

*** -[__NSArrayM removeObject:]: message sent to deallocated instance 0x113dbb10 

附加信息:UIScrollView的委托从未设置。我正在使用ARC。

回答

2

我发现我的问题。 我正在调用从后台线程调用setContentOffset的方法。

BackgroundThread --> My random processing method --> Setup new UIView and add it to UIScrollView --> Call setContentOffset with animations 

上述流程导致崩溃。当我从主线程调用相同的处理方法时,它工作得很好。

显然iOS不喜欢从后台线程调用的动画。

+0

如果iOS和OSX上有一条规则,它永远不会在除主线程之外的任何线程上操作UI。规则1。它并不是说它不喜欢它,它的禁止和苹果证明这是不止一个地方。 – 2012-08-14 11:15:34

+0

是的,我忘了我从背景线程调用此方法的事实。只是以为我会张贴我的答案,以防有人处于同样令人沮丧的位置。 – 2012-08-14 15:31:59

+0

不要忘记选择它作为SO让你的答案!所以人们知道这个问题已经回答了。 – 2012-08-14 16:01:46

0

scrollView中的一个视图正在发布。当你关闭动画的时候,你可能会“跳过”它 - 当它开启时,系统会试图获得一系列变化的“快照”,当它试图访问一个视图繁荣时,你就会去。所以你可以启用Zombies并找出到底是什么类型的对象获取消息,并且在调试器中你可能会“po”那个对象。

另一种方法是编写我们自己的测试动画,将contentOffset一次移动20个像素,并且没有动画,然后观察它何时崩溃(肯定会)!

+0

我尝试了一个手动循环,虽然屏幕有点跳跃到没有任何动画的偏移,但似乎没有造成任何问题。我的循环相当于不带动画调用setContentOffset。 – 2012-08-14 03:38:20

相关问题