Role • strong: equivalent to "retain", an attribute becomes the owner of an object.
• Weak: the attribute is weak pointer. It is automatically set to nil when the object is released. Remember the Outlet
Weak should be used
• Unsafe_unretained: equivalent to the previous "assign", which should be used only for iOS 4
• Copy: similar to the previous copy, copy an object and create a strong association.
• Assign: the object cannot use assign, but the original type (BOOL, int, float) can still be used
Readonly property
Before ARC, we can define a readonly property as follows:
@ Property (nonatomic, readonly) NSString * result;
This implicitly creates an assign property, which is suitable for readonly values. After all, why retain read-only data? However, the following error is reported in ARC:
"ARC forbids synthesizing a property of an Objective-C object
Unspecified ownership or storage attribute"
You must explicitly use strong, weak, or unsafe_unretained. In most cases, strong is the right choice:
@ Property (nonatomic, strong, readonly) NSString * result;
For readonly property, we should always use self. propertyName to access the instance variables (except init and custom getter and setter methods ). Otherwise, modifying the instance change volume will confuse the ARC and cause strange bugs. The correct method is to use class extension to redefine property as readwrite:
. H file:
@ Interface WeatherPredictor
@ Property (nonatomic, strong, readonly) NSNumber * temperature;
@ End
. M file:
@ Interface WeatherPredictor ()
@ Property (nonatomic, strong, readwrite) NSNumber * temperature;
@ End
Dealloc Method
In addition, the dealloc method is not needed most of the time after ARC is enabled, because you cannot call the release method of the instance object or [super dealloc]. If the original dealloc method only releases these objects, Xcode will completely remove the dealloc method. You no longer need to manually release any instance variables.
If your dealloc method processes the release of other resources (non-memory), such as timers and Core Foundation objects, you still need to manually release them in the dealloc method, such as CFRelease (), free. In this case, Xcode retains the dealloc method, but removes all release and [super dealloc] calls. As follows:
-(Void) dealloc
{
AudioServicesDisposeSystemSoundID (soundID );
}
Bytes
Pointer to keep object Lifecycle
The ARC rule is very simple: as long as there is another variable pointing to the object, the object will remain in the memory. When the pointer points to a new value or the pointer no longer exists, the associated object is automatically released. This rule applies to instance variables, synthesize attributes, and local variables.
We can consider the ARC object by "ownership" (ownership): NSString * firstName = self. textField. text;
The firstName variable becomes the pointer to the NSString object, that is, the owner, which stores the content of the text input box.
An object can have multiple owners. In the preceding example, the text attribute of UITextField is also the owner of the String object, that is, two pointers point to the same object:
Then, the text in the input box is changed, and the text attribute points to the New String object. However, the original String object still has an owner (firstName variable), so it will continue to be stored in the memory.
Only when firstName gets a new value or exceeds the scope (when the local variable method is returned, the instance variable object is released), the String object no longer has any owner, and the retain count is reduced to 0, the object will be released.
The firstName and textField. text pointers are called "strong" because they can keep the object's life. By default, all instance variables and local variables are pointer of the strong type.
There is also a "weak" pointer. The weak variable still points to an object, but it is not the owner of the object:
_ Weak NSString * weakName = self. textField. text;
Both the weakName and textField. text attributes point to a String object, but weakName is not the owner. If the content of the text box changes, the original String object will have no owner and will be released. In this case, weakName will automatically become nil, known as "zeroing" weak pointer:
It is very convenient to automatically change the weak variable to nil, which prevents the weak pointer from pointing to the released object. "Swing pointer" and "zombies" can lead to very difficult-to-find bugs. Zeroing weak pointer eliminates similar problems.
The parameters of the CFURLCreateStringByAddingPercentEscapes () function require two CFStringRef objects. The constant NSString can be directly converted because no object needs to be released. However, the text parameter is different and it is an NSString object passed in. Function parameters, like local variables, are strong pointers. This type of object will be retaken at the function entrance, and the object will exist until the pointer is destroyed (this is when the function returns ).
For the text parameter, we want ARC to maintain the ownership of this variable and temporarily use it as a CFStringRef object. In this case, the _ bridge operator can be used to tell ARC not to change the ownership of an object. Just release the object according to common rules.
In most cases, _ bridge should be used when Objective-C objects and Core Foundation objects convert each other. But sometimes we do need to give the ownership of an object in the ARC, or revoke the ownership of an object in the ARC. In this case, we need to use the other two bridging casts:
As long as you call the Core Foundation function named Create, Copy, and Retain, you must use CFBridgingRelease () to safely pass the value to ARC.
Use CFBridgingRelease () to pass ownership from the Core Foundation to Objective-C;
Use CFBridgingRetain () to pass ownership from Objective-C to CoreFoundation;
Use _ brideg to temporarily use a certain type without changing the ownership of the object.
In ARC, if the method name starts with alloc, init, new, copy, and mutableCopy, it returns the retain object. All other methods return the autorelease object. This rule is actually the same as manual memory management. Because the ARC code needs to work with the non-ARC Code.
The following is a good article I have found:
I have added a new knowledge in iOS5, that is, ARC. In fact, I don't like it very much because I am used to managing the memory myself. However, learning is still necessary.
During iOS development, attribute definitions are often related to retain, assign, and copy. I think everyone is familiar with them. I will not introduce them here. There are many related articles on the Internet.
Now let's look at the New Keyword strong, weak, unsafe_unretained in iOS5. it can be similar to learning strong and retain corresponding to previous keywords. weak and unsafe_unretained functions are similar (a little different. We will introduce them later. These two new keywords are similar to assign ). With these new keywords in iOS5, you don't need to manually manage the memory. programmers who transfer from other languages such as java are very useful.
The strong keyword is similar to the retain keyword. When it is used, the reference count is automatically + 1, and the instance can better describe everything.
- @ Property (nonatomic, strong) NSString * string1;
- @ Property (nonatomic, strong) NSString * string2;
There are two attributes,
- @ Synthesize string1;
- @ Synthesize string2;
Guess what results will the following code output?
- Self. string1 = @ "String 1 ";
- Self. string2 = self. string1;
- Self. string1 = nil;
- NSLog (@ "String 2 = % @", self. string2 );
Result: String 2 = String 1
Because string2 is a property defined by strong, reference count + 1 makes them all point to @ "String 1". If you are familiar with retain, This is not difficult to understand.
Next let's look at the keyword weak:
If two attributes are declared as follows:
- @ Property (nonatomic, strong) NSString * string1;
- @ Property (nonatomic, weak) NSString * string2;
And define
- @ Synthesize string1;
- @ Synthesize string2;
What is the output below?
- Self. string1 = @ "String 1 ";
- Self. string2 = self. string1;
- Self. string1 = nil;
- NSLog (@ "String 2 = % @", self. string2 );
Result: String 2 = null
For analysis, string1 is nil because self. string1 and self. string2 point to the same address and string2 does not have a retain memory address, while self. string1 = nil releases the memory. The pointer declared as weak. Once the address pointed to by the pointer is released, these pointers will be assigned as nil. This benefit effectively prevents wild pointers. In the c/c ++ development process, why do Daniel say that when the pointer space is released, the pointer should be assigned NULL. here we use the weak keyword to help us with this step.
Next let's look at unsafe_unretained.
From the name, we can see that unretained and unsafe are similar to weak because it is unretained, but it is unsafe. What is unsafe? Let's look at the instance below.
If two attributes are declared as follows:
And define
- @ Property (nonatomic, strong) NSString * string1;
- @ Property (nonatomic, unsafe_unretained) NSString * string2;
Let's guess, what will happen to the following code?
- Self. string1 = @ "String 1 ";
- Self. string2 = self. string1;
- Self. string1 = nil;
- NSLog (@ "String 2 = % @", self. string2 );
Please note that I have not told you to guess what output will be, because there will be no output at all, and your program will crash.
What is the reason? It is actually caused by a wild pointer, so it is terrible. Why does it cause a wild pointer? Similar to the pointer declared by unsafe_unretained, string2 does not know it has been released because self. string1 = nil has released the memory, so it is a wild pointer. Then the access to the memory of the wild pointer causes crash. Therefore, use the unsafe_unretained keyword as little as possible.
Strong, weak, and unsafe_unretained are often used to declare attributes. To declare a temporary variable, use _ strong, _ weak, _ unsafe_unretained, _ autoreleasing, its usage is similar to that described above.
Let's look at the instance.
- _ Strong NSString * yourString = @ "Your String ";
- _ Weak NSString * myString = yourString;
- YourString = nil;
- _ Unsafe_unretained NSString * theirString = myString;
- // Now all pointers are nil
Let's look at another one:
- _ Strong NSString * yourString = @ "Your String ";
- _ Weak NSString * myString = yourString;
- _ Unsafe_unretained NSString * theirString = myString;
- YourString = nil;
- // Now the pointers of yourString and myString are both nil, while theirString is not nil, but a wild pointer.
_ Autoreleasing usage:
In c/c ++, there is one in objective-c memory management: who allocates and who releases the memory. _ Autoreleasing can delay the object release. For example, if you want to upload an uninitialized object to a method and implement the object in this method, this situation will be when _ autoreleasing is performed. Example:
- -(Void) generateErrorInVariable :( _ autoreleasing NSError **) paramError {
- NSArray * objects = [[NSArray alloc] initWithObjects: @ "A simple error", nil];
- NSArray * keys = [[NSArray alloc] initWithObjects: NSLocalizedDescriptionKey, nil];
- NSDictionary * errorDictionary = [[NSDictionary alloc] initWithObjects: objects forKeys: keys];
- * ParamError = [[NSError alloc] initWithDomain: @ "MyApp" code: 1 userInfo: errorDictionary];
- }
- -(Void) test
- {
- NSError * error = nil;
- [Self generateErrorInVariable: & error];
- NSLog (@ "Error = % @", error );
- }
In this way, even the space applied inside the function can be used outside the function. It is also suitable for the principle of who allocates and who releases the space.
The following code is also for a similar reason, but is applicable when ARC is not enabled:
- -(NSString *) stringTest
- {
- NSString * retStr = [NSString stringWithString: @ "test"];
- Return [[retStr retain] autorelease];
- }
After enabling ARC, you should change it:
- -(NSString *) stringTest
- {
- _ Autoreleasing NSString * retStr = [NSString alloc] initWithString: @ "test"];
- Return retStr;
- }