在快速枚举期间将对象设置为nil

时间:2013-01-08 06:00:51

标签: objective-c ios memory-management fast-enumeration

我想通过数组枚举一个对象为'nil',如下所示:

for(Object* object in array){
    object = nil;
}

然后Xcode告诉我'默认情况下,无法在ARC中修改快速枚举变量;声明变量__strong以允许它。'

这意味着这样做:

for(Object __strong* object in array){
    object = nil;
}

这似乎是多余的。据我所知,声明对对象的强引用会使其保留计数增加1,而将其保留计数减少1。那么,如何在枚举数组的同时将对象设置为nil

我正在使用ARC。

3 个答案:

答案 0 :(得分:3)

请参阅Clang“Objective-C自动参考计数”文档中的Fast enumeration iteration variables

  

如果在Objective-C快速条件下声明变量   枚举循环,并且变量没有明确的所有权   限定符,然后它与const __strong和对象合格   在枚举期间遇到实际上未保留

     

<强>原理
  这是一种因为快速而成为可能的优化   枚举循环允许在期间保留对象   枚举,集合本身不能同步   改性。可以通过显式限定变量来覆盖它   使用__strong,这将使变量再次变为可变并导致   用于保留遇到的对象的循环。

因此,默认情况下,循环变量是不可变的,并且出于性能原因,不会增加当前对象的保留计数。

如果显式地将循环变量声明为__strong,则它是一个可变的强引用,并且当前对象的保留计数增加,并且将循环变量设置为nil会减少保留计数再次。但这样做并不会释放对象或将其从数组中删除,因为该数组拥有另一个对该对象的强引用。

答案 1 :(得分:2)

快捷方式:

[array removeAllObjects];

如果您希望阵列仍然包含x个项目但不包含当前项目中的项目,则可以使用NSNull占位符:

for (NSUInteger i = 0; i < [array count]; i++)
    [array replaceObjectAtIndex:i withObject:[NSNull null]];

请记住,数组只保存对象的引用。如果数组不再包含对它们的引用,则内存管理将启动并释放对象(但仅在没有其他任何内容的情况下)。

答案 2 :(得分:0)

在评论中,您已经透露,您的意图是取消分配数组中的对象,无论其他内容是否也拥有对它们的所有权声明。这违反了核心内存管理原则:不得释放您不拥有的内存。做你想做的事情是个坏主意。

必须允许其他对象管理自己的内存。也许数组中的一个项是UI对象正在显示的一段数据。当UI对象需要刷新自身,并查找已从其下面解除分配的数据时,您的应用程序可能会崩溃。

从这个数组的角度来看,你可以做两件事。您可以将数组作为一个整体释放,这将放弃数组对包含对象的声明;如果他们不归其他任何东西,他们将被取消分配。如果您想保留数组本身,但要释放其所有项目,请使用removeAllObjects;再次,如果没有别的东西,这些物品将被解除分配。

重要的一点是,如果 拥有其他东西拥有它们,那可能是有充分理由的,而且你不应该绕过它。