2011-11-25 34 views
0

我有一个方法来刷新UIScrollView的内容。在ScrollView中有几个UIImageViews和一些UILabels。IndexOutOfBounds通过子视图循环?

我做清洁滚动视图的内容与下面的代码:

for (int i = [publicationsScrollView.subviews count] -1; i>=0; i--) { 
    NSLog(@"Deleting SubView: %@", [[publicationsScrollView.subviews objectAtIndex:i] class]); 
    if ([[publicationsScrollView.subviews objectAtIndex:i] isKindOfClass:[UIButton class]] || [[publicationsScrollView.subviews objectAtIndex:i] isKindOfClass:[UIButtonLongTap class]] || [[publicationsScrollView.subviews objectAtIndex:i] isKindOfClass:[UILabel class]] || [[publicationsScrollView.subviews objectAtIndex:i] isKindOfClass:[UIImageView class]]) { 
     NSLog(@"Deleting SubView: %@", [[publicationsScrollView.subviews objectAtIndex:i] class]); 
     [[publicationsScrollView.subviews objectAtIndex:i] removeFromSuperview]; 
    } 
    if ([[publicationsScrollView.subviews objectAtIndex:i] isKindOfClass:[iCarousel class]]) { 
     NSLog(@"carousel: View is in Scrollview"); 
    } 
} 

此代码运行良好了一些日子。现在我在控制台刷新期间收到一个错误:

refreshWorkSpace: deleting all subviews (11) 
2011-11-25 14:04:52.826 CatalogService[45054:fb03] Deleting SubView: UILabel 
2011-11-25 14:04:52.827 CatalogService[45054:fb03] Deleting SubView: UILabel 
2011-11-25 14:04:52.839 CatalogService[45054:fb03] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 10 beyond bounds [0 .. 9]' 
*** First throw call stack: 
(0x1e8c052 0x231fd0a 0x1e78db8 0x6945 0x5826 0x1e8dec9 0xddc5c2 0xddc55a 0xe81b76 0xe8203f 0xe81bab 0xecfa99 0xed1407 0xe0193f 0xe01c56 0xde8384 0xddbaa9 0x28b6fa9 0x1e601c5 0x1dc5022 0x1dc390a 0x1dc2db4 0x1dc2ccb 0x28b5879 0x28b593e 0xdd9a9b 0x2e6d 0x2de5 0x1 

我不明白这里发生了什么。我循环通过子视图(计数应该给我现有子视图的数量!?)。为什么指数会超出界限!

+0

这很奇怪。你确定子视图不会被其他函数同时删除吗?你确定没有其他的源代码片段可以影响这个bug吗? – Piotr

+0

我正在通过代码爬行来检查。到目前为止我找不到任何东西。 – MadMaxAPP

+0

它总是在相同的子视图上崩溃... – MadMaxAPP

回答

1

我会怀疑异常被抛出在这条线:

if ([[publicationsScrollView.subviews objectAtIndex:i] isKindOfClass:[iCarousel class]]) { 
[[publicationsScrollView.subviews objectAtIndex:i] removeFromSuperview]刚刚在那里执行将不再索引“我”的对象的情况下

。这只会发生在数组中最后一个子视图是你删除的类型之一的情况下 - 否则访问将是无害的。

要解决此问题,您可以在removeFromSuperview调用后添加continue

+0

似乎工作。感谢您在这个基本问题上的帮助! – MadMaxAPP

0

也许尝试用快速列举替换for循环,如:

for (UIView *aView in publicationsScrollview.subviews) { 

    .... rewrite code to reference aView instead of using objectAtIndex 
} 

,看看你会得到相同的行为。

+0

它只是怪我,你说,它崩溃的I = 3,但是崩溃日志似乎暗示其超出其范围为I = 10 – Damien

+0

他通过移除子视图修改子视图数组,所以快速列举将抛出有关异常在迭代过程中突变数组。 – JosephH

+0

@JoesphH - 好赶上! – Damien

0

在第一个如果,如果它进入你删除子视图。所以,你减少了子视图count数组。 之后,你再次尝试采取子视图,在第二个,如果这个子视图被删除,这就是为什么它崩溃。