2013-04-22 51 views
7

什么是关键字copy在ARC什么是“复制”在ARC

我找到copy(关键字)的角色的角色可以在ARC被使用,而retainrelease不能使用。另外在ARC中copy的作用与copy在MRC中的作用是一样的吗?如果是,在ARC中copy是否使retainCount +1?

我曾看到迈克灰博客约雅倩说:

你需要明确地复制你传递的ID参数块:

[myArray addObject: [^{ DoSomethingMagical(); } copy]]; 

,但是当我测试这样的代码(不使用copy),它的效果也很好。

NSArray *array = [[NSArray alloc] initWithObjects:^{NSLog(@"hahaha");}, nil]; 

[self test:[array objectAtIndex:0]]; 

- (void)test:(void (^)(void))completion 
{ 
       completion(); 
} 

这是否意味着没有必要copy块,当它作为id类型?

+1

通过在MRC或ARC中使用副本不会增加保留计数。 – Rakesh 2013-04-22 14:35:06

+3

@rakesh更准确地说“ARC/MRR中的保留数*可能会增加”,因为它是一个实现细节。对于NSMutableString?你会得到一份副本。对于NSString?将保留计数加1并返回相同的对象。 – bbum 2013-04-22 15:31:22

+0

请注意,在您的示例中的块可能是一个静态块,因此,您的代码可能只是巧合“工作”。 – bbum 2013-04-22 15:32:18

回答

5

是的,copy在ARC的作用是一样的copy在MRR

copy作用将调用copyWithZone:方法。当它发送给可变对象时,它将返回一个克隆不可变对象,其retainCount为1.当它发送给不可变对象时,它将不会复制,它将返回对象本身,但将返回retainCount +1。

所以,当你在ARC使用副本,您可以使用像这样:object1 = [object2 copy]; ARC将管理object1,当再object1由ARC发布的retainCount,该object2的retainCount将有相应的变化。所以你不用担心记忆。

关于block需要copy时传递为id参数。

apple document说:

通常情况下,你不应该需要复制(或保留)块。如果您希望在 销毁宣称的范围之后使用该块,则只需要 即可进行复制。复制移动的 块的堆

和As ughoavgfhw said

块类似于用于内存管理其他的目的,但不是相同 。创建访问局部变量的块时,将在堆栈上创建 。这意味着只有存在 作用域时它才有效。为了以后保存该块,您必须将其复制,然后将其复制到堆中

1

当您在ARC中使用copy时,它与没有ARC时的做法相同,即它创建接收副本的对象的副本(它在内存中创建一个新的对象实例),并创建一个strong与执行代码的对象。
这意味着对象的副本现在具有1的保留计数,但这与ARC无关,因为这是自动处理的。

4

复制只是名称所暗示的意思。它返回对象的一个​​副本。假设你有一个可变对象,并且你有一个指向它的指针。然后你在代码中的其他地方引用它,ARC会假设你想指向同一个对象并保留它。在这种情况下,如果您修改其中任何一个都会反映这些更改。如果你点它有copy你会得到一个新的对象,并修改一个不会影响其他:

NSMutableArray* objA = [NSMutableArray new]; 
NSMutableArray* objB = objA; 
/* adding an object to either will be in both since they point to the same object*/ 
objB = [objA mutableCopy]; 
/*adding an object to one WILL NOT affect the other, they are different, distinct objects*/ 

在文档浏览:

http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html#//apple_ref/doc/uid/TP40007502-CH6-SW1

它提到,当块被复制的所有Objective-C对象都会收到一个强引用,以便它们在执行该块之前不会超出范围。

相关问题