在快速枚举期间将对象设置为nil
我想通过数组枚举一个对象为’nil’,如下所示:
for(Object* object in array){ object = nil; }
然后Xcode告诉我’默认情况下,不能在ARC中修改快速枚举变量; 声明变量__strong以允许这个。
这意味着这样做:
for(Object __strong* object in array){ object = nil; }
这似乎是多余的。 据我了解,声明对对象的强引用会使其保留计数增加1,而将其保留计数减少1。 那么,如何在枚举数组的同时将对象设置为nil
?
我正在使用ARC。
请参阅Clang“Objective-C自动引用计数”文档中的快速枚举迭代变量 :
如果在Objective-C快速枚举循环的条件中声明变量,并且变量没有显式所有权限定符,则使用
const __strong
限定它,并且实际上不会保留枚举期间遇到的对象。合理
这是一种可能的优化,因为快速枚举循环允许在枚举期间保留对象,并且不能同步修改集合本身。 它可以通过使用__strong
显式限定变量来覆盖,这将使变量再次变为可变并导致循环保留它遇到的对象。
因此,默认情况下,循环变量是不可变的,并且出于性能原因,不会增加当前对象的保留计数。
如果显式地将循环变量声明为__strong
,则它是一个可变的强引用,并且当前对象的保留计数增加,并且将循环变量设置为nil
会再次减少保留计数。 但这样做不会释放对象或将其从数组中删除,因为该数组拥有对该对象的另一个强引用。
快捷方式:
[array removeAllObjects];
如果您希望数组仍然包含x个项目但不包含当前项目中的项目,则可以使用NSNull
占位符:
for (NSUInteger i = 0; i < [array count]; i++) [array replaceObjectAtIndex:i withObject:[NSNull null]];
请记住,该数组仅保存对其对象的引用。 如果数组不再包含对它们的引用,则内存管理将启动并释放对象(但仅在没有其他任何内容的情况下)。
在评论中,您已经透露,您的意图是释放数组中的对象,无论其他内容是否也拥有对它们的所有权声明。 这违反了核心内存管理原则:您不能释放您不拥有的内存。 做你想做的事是个坏主意。
您必须允许其他对象管理自己的内存。 也许数组中的一个项是UI对象正在显示的一段数据。 当UI对象需要刷新自身,并查找已从其下面解除分配的数据时,您的应用程序可能会崩溃。
从这个数组的角度来看,你可以做两件事。 您可以将数组作为一个整体释放,这将放弃数组对包含对象的声明; 如果他们不归其他任何东西,他们将被取消分配。 如果要保留数组本身,但释放其所有项,请使用removeAllObjects
; 再次,如果没有其他东西拥有它们,项目将被解除分配。
重要的一点是,如果其他东西确实拥有它们,那可能是有充分理由的,而且你不应该绕过它。