Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the role of the "copy" in the ARC

What is the role of keyword copy in the ARC

I find the copy(keyword) can be used in ARC while retain and release cannot be used. Moreover is the role of copy in ARC is the same as the role of copy in MRC? If yes , does copy make the retainCount +1 in ARC?

And I have seen mike ash blog about ARChe said :

you need to explicitly copy blocks that you pass as id parameters:  

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

but when I test code like this (without using copy) it works well too.

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

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

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

Does it mean that there is no need to copy block when it used as an id type?

like image 861
shane dell Avatar asked Apr 22 '13 14:04

shane dell


3 Answers

Yes , the role of copy in ARC is the same as the role of copy in MRR

The copy will invoke the copyWithZone: method . when it send to the mutable object , it will return a clone immutable object , which retainCount is 1. When it send to the immutable object , it will not copy , it will return the object itself , but the retainCount +1.

So when you use copy in ARC , you can use like this : object1 = [object2 copy]; ARC will manage the retainCount of the object1 , when then object1 is released by ARC , the object2's retainCount will be a corresponding change. So you do not worry about the memory.

About the block need be copy when pass as id parameters.

the apple document said :

Typically, you shouldn’t need to copy (or retain) a block. You only need to make a copy when you expect the block to be used after destruction of the scope within which it was declared. Copying moves a block to the heap

and As ughoavgfhw said :

Blocks are similar to other objects for memory management, but not the same. When a block which accesses local variables is created, it is created on the stack. This means that it is only valid as long as its scope exists. To save this block for later, you must copy it, which copies it to the heap

like image 63
Guo Luchuan Avatar answered Nov 07 '22 17:11

Guo Luchuan


Copy does just what the name implies. It returns a copy of the object. Say you have a mutable object and you have a pointer to it. You then reference it somewhere else in the code and ARC will assume you want to point at the same object and retain it for you. In this case if you modify either of them both will reflect the changes. If you point at it with a copy you will get a new object, and modifying one will not affect the other:

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*/

In the docs here:

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

It mentions that when blocks are copied all of their Objective-C Objects receive a strong reference so that they don't drop out of scope before the block is executed.

like image 37
utahwithak Avatar answered Nov 07 '22 15:11

utahwithak


When you use copy in ARC, it does the same as without ARC, i.e. it creates a copy of the object that is receiving the copy (it creates a new object instance in memory), and creates a strong relationship to the object that executes the code.
This means that the copy of the object now has a retain count of 1, but this is of no relevance for you in ARC, since this is handled automatically.

like image 40
Reinhard Männer Avatar answered Nov 07 '22 17:11

Reinhard Männer