Preface
The previous article described the reference counting mechanism for memory management, and also the code to understand how to manage memory through reference counting. This article describes a memory management mechanism that the system implements for us-property parameter properties. Before we introduce the use of attribute parameters for memory management, let's look at what the attribute parameters are and how they work.
Property parameters
The syntax for declaring a property is: @property (attribute [, Property 2, ...]) type name;
Attributes are divided into 3 categories:
1. Read-write properties (writability) include: readwrite/readonly
2.setter semantics (Setter semantics) contains: assign/retain/copy
3. Atomicity (atomicity) consists of: nonatomic
The meanings of each attribute are specified below
Readwrite/readonly:
Determines whether to generate a set accessor, ReadWrite is the default property, generates getter and setter methods, ReadOnly only generates getter methods, does not generate setter methods.
The ReadOnly keyword means that the setter will not be generated, so it cannot be used in combination with copy/retain/assign.
These properties are used to specify the semantics of the set accessor, that is, these properties determine how the data member is assigned a new value.
Assign/retain/copy:
Assign
Direct assignment, the index count does not change, for simple data types, such as: Nsingeter, cgfloat, int, char, and so on.
Retain
A copy of the pointer, using the original memory space.
The index count of the object is added 1.
This property can be used only for Objective-c object types, not for core Foundation objects. (for obvious reasons, retain increases the object's reference count, and neither the base data type nor the core Foundation object has a reference count).
Copy
A copy of the object, a new request for a memory space, and copy the original content to that space.
The index count for the new object is 1.
This property is valid only for those object types that implement the Nscopying protocol.
Many of the objects in Objective-c are best used with retain, some special object (for example: string) using Copy.
Nonatomic:
Non-atomic access, non-synchronous, multi-threaded concurrent access improves performance. If this attribute is not added, the default is two access methods are atomic transaction access. The default value is atomic, which is an atomic operation.
(Atomic is a thread-protection technique used by OBJC, basically to prevent the data from being read by another thread when the write is not completed.) This mechanism is resource-intensive, so nonatomic is a very good choice on small devices such as the iphone, if there is no communication programming between multiple threads. )
Memory management
The setter semantics part of the property attribute parameter is the memory management implementation of the property.
Assign parameters
Declares a human #import <Foundation/Foundation.h> #import "HXBook.h" @interface hxperson:nsobject@property (Nonatomic, assign) int age;/** Note here is assign*/@property (nonatomic, assign) Hxbook *book; @end declaration a book class #import <foundation/ Foundation.h> @interface Hxbook:nsobject@property (nonatomic, assign) cgfloat price; @end
We create a person instance, a book instance in the main function, and assign the book instance to the book attribute of the person instance.
int main (int argc, const char * argv[]) { @autoreleasepool { //Create a person instance Hxperson *person = [[Hxperson alloc] I NIT]; Person.age =; Create a number instance hxbook *b1 = [[Hxbook alloc] init]; B1.price = 12.3; Man possesses a book person.book = b1; } return 0;}
We declare the book as the Assign property, and according to the previous introduction assign is just a simple assignment, we can also manually implement book getter and Setter Methods, as follows:
-(void) Setbook: (Hxbook *) Book { _book = Book;} -(Hxbook *) book { return _book;}
When the main function executes to Person.book = B1, the corresponding graph in memory is probably as follows:
Because book uses assign, which is a weak reference, when declaring, it uses a dashed line to represent a weak reference, and the implementation represents a strong reference.
In non-ARC environments (changing the project to a non-arc environment), you need to manually free up memory. Now do the release memory operation under Person.book = B1, and call the following method.
First release the B1.
[B1 release];
After the method executes, the Hxbook object in memory does not have a strong pointer reference, the in-memory Hxbook object is freed, and the system automatically calls the Dealloc method. The figure is probably as follows:
Because the Hxbook object in memory is freed, because the person is only a weak reference to the in-memory Hxbook object, all the person no longer has an in-memory Hxbook object. Any messages sent to Person.book and B1 at this point will give an error.
All we can do is set the object's pointer to nil when the object's Retaincount is 0, and the pointer is empty. This sends a message to the object without an error (the object pointer points to nil, which sends a message to nil).
[B1 release];b1 = nil;
Release the person again.
[Person release];
After the method executes, there is no object in memory at this time, the picture is blank (do not post it).
Note: The principle of memory release is used here: If an object does not reference it with a strong pointer, it is freed.
Retain parameters
As you can see from the above, if the Hxbook object in memory is freed, the books that are owned by the person will be released. Obviously this is not what we want, what we want is: when the book is created, assigned to a person, people can always have the book instance, even if the book is released, people have the book is still in (meaning once owned, has been there). How do we do that?
Before declaring the properties of the book in the person's. h file, we used the assign, and now we change the assign to retain. At this point the getter and setter methods for the book are not so simple, in the ARC environment, the system will automatically help us in the appropriate place to add memory management code. But how does the retain attribute parameter be implemented under non-arc?
As I said before, the retain attribute parameter is a copy of the pointer, using the original memory space. The index count of the object is added 1.
The Retain property parameter is implemented as follows:
-(void) Setbook: (Hxbook *) book { [_book release];//first releases the previous instance _book = [and then retain];//a copy of the current instance (pointer copy), Assign value to attribute}-(Hxbook *) book { return _book;}
This time we will analyze the execution of the Code, as well as the corresponding.
int main (int argc, const char * argv[]) { @autoreleasepool { //Create a person instance Hxperson *person = [[Hxperson alloc] I NIT]; Person.age =; Create a number instance hxbook *b1 = [[Hxbook alloc] init]; B1.price = 12.3; Man possesses a book person.book = b1; } return 0;}
The program runs to Person.book = B1, and then the corresponding and previous are different,
As you can see, when B1 is released, because there is still a strong reference to the Hxbook object in memory, the Hxbook object in memory is not freed so that the person can always have the book instance. Here is the analysis process
We do the release operation and still call the release method manually. The first is B1.
[B1 release];
After execution, the B1 will be released, and the corresponding and previous is still different.
Sending a message to B1 at this point will not cause an error, as the B1 is not destroyed and the memory still exists.
So the person has always been the owner of the book instance.
The person is released.
[Person release];
When the method is executed, a pointer to an in-memory Hxperson object is freed, causing no strong pointer to point to the Hxperson object in memory, the Hxperson object in memory is also freed, and all memory is blank (not mapped).
The corresponding relationship of attribute parameters in arc and non-ARC environments is as follows:
Assign correspondence weak
Retain Correspondence strong
This means that strong and weak are recommended in ARC environments to represent strong and weak pointers (strong and weak references). Use retain and assign to represent strong and weak pointers in non-ARC environments (strong and weak )
Memory management in Arc and non-ARC environments will be described later.
Memory Management-property