1. What is ARC?
(1), ARC full name is automatic Reference counting, which is the automatic reference count, automatically counts the reference number of objects in memory, and automatically releases the object when appropriate;
(2), the use of arc in the project is very simple: just write the code as usual, but never write retain, release and autorelease three keywords;
(3), before using arc, need to manually manage memory count, this mechanism is called MRC, that is, manual reference count (Manual Referecen counting);
(4), ARC is the feature of the Objective-c compiler, not the run-time feature or garbage collection mechanism , the only thing that arc does is to automatically insert the release or autorelease at the appropriate location when the code is compiled. As you did in the previous MRC;
(5), now only need to point to the object with a pointer, as long as the pointer is not empty, the object will remain on the heap. When you point the pointer to a new value, the original object will be release once. This applies to instance variables, synthesize variables, or local variables. Like what:
NSString *firstname = Self.textField.text;
FirstName now points to the NSString object, at which point the object (TextField's content string) will be hold;
(6), one of the basic rules of arc is that it will not be destroyed as long as an object is pointed to by any of the strong pointers. If the object is not pointed to by any strong pointer, it will be destroyed. By default, all instance variables and local variables are of type strong. It can be said that the strong type of pointer in the behavior and the MRC era retain property is relatively similar, and arc in the default pointer type is strong;
(7), use arc no longer need to care about when retain, when release, but this does not mean you can not think about memory management, you may need to ask yourself this question frequently: who is holding this object?
For example, the following code assumes that the array is an Nsmutablearray array and that there is at least one object in it:
ID obj = [array objectatindex:0];
[Array removeobjectatindex:0];
NSLog (@ "%@", obj);
These lines of code should have been dropped in the MRC era, because the No. 0 object in array was immediately destroyed after it was removed, so obj pointed to a dealloced object, so NSLog will appear exc_bad_access. In arc, because obj is strong, it holds the first object in the array, and the array is no longer the only holder of that object. Even if we remove obj from the array, it will not be destroyed because it has been held by another pointer;
(8), ARC also has some shortcomings, for beginners, may only use arc on the Objective-c object (also inherit from the NSObject object), but if it involves the lower level of things, such as malloc () in the Core Foundation or free () and so on, arc beyond, this time still need to manually do the memory management;
(9), you must be awake at all times who holds what objects, and when these holders should turn to nil.
2. About MRC:
(1), when using MRC, in order to ensure that an object exists, each time you create a reference to this object, you need to manually count the number of references, the number of references plus 1, using the following statement:
[Xxxclass retain];
(2), when the object is no longer needed (but may need to be referenced elsewhere), reduce the number of references by 1, using the following statement:
[Xxxclass release];
(3), when the reference number of the object is 0 o'clock, in theory generally no longer need to refer to this object, then you can release its memory, by using the NSObject class of Dealloc () method to operate;
(4), when the object has been destroyed, but also point to the reference to the object, called the hanging pointer . Sending a message to the hanging pointer may cause the system to crash;
(5), when an object is created in a defined method, and the object is eventually used as the return value of the method, the object must be retained for return and cannot be destroyed when the method's statement is finished. Then you cannot use the release () method to rudely dispose of the object, you can use the following statement:
[Xxxclass autorelease];
This method adds this object to the auto-release pool Autoreleasepool, which is handled as follows, assuming that the object created in the method is Xclass:
Xclass *xclass = [[[[Xclass alloc] init] autorelease];
or it is written on the return statement:
return [Xclass autorelease];
(6), when using a class from the foundation, UIKit, AppKit framework in a program, you need to first create an auto-free pool, with the statement:
@autoreleasepool {
...
}
when executed to the end of Autoreleasepool, the system frees the pool, and for all objects that are sent autorelease messages to be added to the pool, the system automatically sends a release message to those objects. When the reference count of an object has been reduced to 0 o'clock (so that if an object's reference count is greater than 0, it is still not freed), the DEALLOC message is emitted and the memory is freed;
(7), the automatic release of the pool is not the actual object, is simply a reference to the object;
(8), any objects that inherit from NSObject and are prefixed with alloc, copy, Mutablecopy , and new are not automatically freed and need to be managed manually;
3. Properties assign, retain and copy:
(1), assuming that an attribute p is declared with one of the above attributes, then when the value of P is newvalue:
SELF.P = newvalue;
The effects of each feature are as follows:
(2),assign: This is the default attribute, after using this feature, the assignment statement is equivalent to:
P = newvalue;
(3),retain: An assignment statement is equivalent to:
if (P! = newvalue) {
[P release];
p = [NewValue retain];
}
(4),copy: An assignment statement is equivalent to:
if (P! = newvalue) {
[P release];
p = [newvalue copy];
}
4. Further understanding of this three features:
(1), suppose you allocate a piece of memory and store a value in it, and then assign the address of this memory to pointer a, and you want pointer b to share the memory, so you assign a directly to B. This is assign, a simple pointer copy, at which A and B point to the same piece of memory.
The problem with assign is that if a no longer needs this memory, it will not be able to directly free memory because a does not know whether B is still using the memory, and if a releases B but still uses the memory, then B becomes the hanging pointer;
(2), and retain and assign are similar, but also the pointer copy, but retain in the process of copying the pointer to use the reference count: When the memory is allocated and assigned to a, the reference count is 1, when a is assigned to B, the reference count is increased to 2.
So if a no longer uses this memory, it simply needs to subtract the reference count by 1, indicating that it no longer owns the memory. b The reference count is also reduced by 1 when the memory is no longer used. When the reference count becomes 0, the system knows that the memory is no longer referenced by any pointers and can be released directly;
(3), copy is used when you do not want a and B to share a piece of memory. A and B will each have their own memory after the use of copy;
(4), why the @implementation definition method to use the property to add self.
The setter method is invoked because self is used. If the previous does not add self, the equivalent of assign method to invoke the property, Retaincount will not add 1.
5, an example can further understand the three features:
NSString *ahouse =[[nsstring alloc] initwithstring:@ " set of houses"];
The above code performs the following two actions:
(1), allocating a memory on the heap to store @ " set of houses" : Assume that the memory address is 0x0011 and the content is @ " set of houses" ;
(2), allocate a piece of memory on the stack to store Ahouse , assuming that the address is  0X00AA , content is 0x0011 (that is, the address of a "set of houses");
The effects of three features are shown below:
(1), Assign : nsstring * bhouse = ahouse ;
At this time Bhouse and Ahouse are identical, the addresses are  0X00AA, the content is 0x0011, that is, bHouse Just the alias of the ahouse, for any one operation is equal to another operation. Therefore retainCount does not increase (a key, both sides common);
(2), retain case: nsstring * bhouse = [ ahouse retain ];
At this point the address of bHouse is still 0x00aa , and the contents of the store are still 0x0011. But Ahouse's retaincount will add 1. So both Ahouse and Bhouse can manage the memory of "a house". (Two keys, one for each);
(3), copy : nsstring * bhouse = [ ahouse copy ];
At this time will re-open a memory on the heap storage @ "A house", assuming that 0x0022, content is @ "A house", at the same time will be on the stack for the Bhouse allocation of space, assuming that the address is 0x00cc, the content is 0x0022. Ahouse Retaincount will not change, Bhouse has its own retaincount (two sets of houses, each one of the keys, each open, unrelated).
6, when to use retain when to use assign? Take the 5 code as an example to explain:
(1), when to use assign:
Broken House, simple house can share the key, such as: basic type (simple type, atomic type) Nsinteger, Cgpoint, cgfloat, C data type (Int,float,double,char, etc.);
(2), when to use copy:
Classes that contain mutable subclasses that can be deeply copied, such as Nsarray, Nsset, Nsdictionary, NSData, Nscharacterset, Nsindexset, NSString, and so on. It is also important to note that the derived Mutable class cannot be copied, otherwise the initialization will be problematic.
(3), when to use retain:
Other NSObject and their subclass objects (most).
7, about atomic and nonatomic characteristics:
(1), the atomic attribute indicates that the compiler-generated setter and getter methods are atomic operations, and the Nonatomic attribute indicates that the setter and getter methods do not implement atomic operations;
(2), atomic operation is in the case of multi-threaded, a resource will be access to its thread monopoly, before the thread can use this resource, other threads cannot intervene;
(3), so when the setter and getter methods of the properties of the atomic attribute are called, other methods cannot access this property. The Nonatomic attribute of a property indicates that it cannot monopolize its setter and getter methods;
(4), property default is atomic feature;
(5), so in the case of multithreading to use the atomic feature, and this mechanism is required to consume memory, so if you do not need a multi-threaded environment, the attribute should be declared as nonatomic to save memory;
(6), so there will be atomic corresponding to multi-threading, and Nonatomic is a ban on multithreading this argument (in fact, it should be said that the use of nonatomic will prohibit multithreading).
8. If you define an array property of a retain attribute:
@property (nonatomic, retain) Nsmuatablearray *data;
Then use the data in other locations in the program, if initialized with the following statement:
data = [Nsmutablearray array];
The array method creates an automatically freed array and assigns it to data, and the data array is destroyed at the end of the current event because the auto-free pool cleans up after the event ends. If you want this array to survive the event loop, you can use the following 3 ways:
(1), data =[[nsmutablearray array] retain]; Direct retain increase Retaincount
(2), Data =[[nsmutablearray alloc] init]; Alloc objects are not destroyed by the auto-release pool
(3), Self.data =[nsmutablearray array]; Add self. Will use the Setter method, then @property
The retain will work.
These 3 methods will cause the object not to be automatically destroyed by the automatic free pool, then you need to overwrite the Dealloc method:
-(void) Dealloc {
[Data release];
[Super Dealloc];
}
9. Some conclusions about MRC:
(1), send a retain message to an object can keep this object will not be destroyed, but after the use of this object to send a release message to release;
(2), sending a release message to an object does not mean that the object will be destroyed, and whether the destruction depends on the object's reference count, the release message will only let the object's reference count minus 1, when the reference count is reduced to 0 o'clock object will be destroyed;
(3) to dispose of any object that uses the Alloc, new, copy, Mutablecopy, or retain methods, or attributes with retain and copy attributes, the Dealloc method needs to be overwritten;
(4), the automatic release of the pool when emptied, the system will send a release message to each object in the pool, and then for those whose reference count is reduced to 0 of the object, the system will send a DEALLOC message to destroy these objects;
(5), if an object needs to be used as the return value of a method, that is, an object in the method after the method call must continue to survive, you can use the Autorelease method with this object. The Autorelease method does not affect the reference count, only the object is marked for delay release;
(6), when the application terminates, all objects will be released;
(7), in the process of running a program, after an event is processed, the system empties the auto-free pool and waits for the next event to occur. If you want a member object or an instance variable to exist after the auto-free pool is emptied, you can send a retain message to it, as long as the object or variable's reference count is greater than the number of autorelease messages sent, it will survive the cleanup of the auto-free pool.
10, about strong variables and weak variables:
(1), strong variable use keyword strong, weak variable use keyword weak;
(2), usually all object pointer variables are strongly variable by default, the strong variable is initialized to 0 by default . However, the default attribute is not strong, the default attribute is Unsafe_unretaind (equivalent to assign);
(3), the method of specifying the weak attribute for an object variable or property is as follows:
__weak UIView *parentview;
@property (Weak, nonatomic) UIView *parentview;
(4), the strong keyword is similar to retain, using its reference count will automatically add 1, that is, it points to the content will be reserved for it, and will not be destroyed for no reason. Use the following code to illustrate:
...//The following definitions are first
@property (nonatomic, strong) NSString *string1;
@property (nonatomic, strong) NSString *string2;
...
@synthesize string1;
@synthesize string2;
...//Case 1:
Self.string1 = @ "xxxx"; Retaincount = 1
Self.string2 = self.string1; Retaincount = 2
Self.string1 = nil; Retaincount = 1
NSLog (@ "String 2 =%@", self.string2);
The result of the output is: String2 = xxxx
...//Condition 2,string2 is declared as weak feature:
@property (nonatomic, weak) NSString *string2;
...
Self.string1 = @ "String 1"; Retaincount = 1
Self.string2 = self.string1; Retaincount = 1
Self.string1 = nil; Retaincount = 0
NSLog (@ "String 2 =%@", self.string2);
The result of the output is: String2 = null
(5), so the strong variable will point to the object's Retaincount plus 1, can be guaranteed to hold, and the weak variable cannot affect the Retaincount to the object; The weak variable has one advantage: as shown in the example above, if the object that the weak variable points to is freed, the variable is automatically set to nil;
(6), when two objects hold each other's references, and both sides are strong variables, will produce a circular reference, will cause these two objects persist, cannot be destroyed. This is the time to declare one of the objects as a weak variable to solve the problem;
OC Foundation 15: Memory management and automatic reference counting