Objective-C basic notes (3) OC memory management, objective-coc
Objective-C memory basic management
Each variable in OC Stores the reference counter. When the reference counter of this object is 0, the object will be recycled. When an object is created using alloc, new, or copy, the Reference Counter of the object is set to 1.
Send a retain message to the object, which can include the reference counter plus 1.
Send a release message to the object to enable reference counter-1.
When the OC is destroyed, a dealloc message is sent (not directly called, called by the system). You can rewrite the dealloc method to release resources in the method.
You can send a retainCount message to an object to obtain the current reference counter of the object.
First, create a project.
Next, disable the ARC in the settings of the project.
Book. h file
#import <Foundation/Foundation.h>@interface Book : NSObject@property float price;- (id)initBook:(float)price;@end
Book. m file
# Import "Book. h "@ implementation Book @ synthesize price = _ price; // constructor-(id) initBook :( float) price {if (self = [super init]) {_ price = price;} NSLog (@ "the price is % f's book purchased", _ price); return self ;}// destructor-(void) dealloc {NSLog (@ "the book whose price is % f has been released", _ price); [super dealloc] ;}@ end
Student. h file
#import <Foundation/Foundation.h>#import "Book.h"@interface Student : NSObject@property int age;@property Book *book;- (void)setBook:(Book *)book;- (id)initStudent:(int)age;@end
Student. m file
# Import "Student. h "# import" Book. h "@ implementation Student @ synthesize age = _ age; @ synthesize book = _ book;-(void) setBook :( Book *) book {if (_ book! = Book) {// first subtract one from the original book counter // if it is nil before (unlike the NULL pointer in java) [_ book release]; [book retain]; _ book = book ;}// constructor-(id) initStudent :( int) age {if (self = [super init]) {_ age = age;} NSLog (@ "student with age % d created", _ age); return self ;}// destructor-(void) dealloc {[_ book release]; NSLog (@ "Students of age % d are released", _ age); [super dealloc] ;}@ end
Main. m file
# Import <Foundation/Foundation. h> # import "Student. h "# import" Book. h "void buyBook (Student * stu) {Book * book1 = [[Book alloc] initBook: 101.5]; // who created and released stu. book = book1; [book1 release]; Book * book2 = [[Book alloc] initBook: 98.5]; stu. book = book2; [book2 release];} void readBook (Student * stu) {NSLog (@ "students whose age is % I are reading books whose price is % f", stu. age, stu. book. price);} int main (int argc, const char * argv []) {@ autoreleasepool {// the counter is 1 Student * stu = [[Student alloc] initStudent: 21]; // buy a book buyBook (stu); // read a book readBook (stu); // clear the counter 0 and release the memory [stu release];} return 0 ;}
Output result:
23:11:19. 510 memory management [698: 46519] Students of age 21 created
23:11:19. 512 memory management [698: 46519] the price is 101.500000 of books purchased
23:11:19. 512 memory management [698: 46519] the price is 98.500000 of books purchased
23:11:19. 512 memory management [698: 46519] books with a price of 101.500000 were released
23:11:19. 512 memory management [698: 46519] 21-year-olds are reading 98.500000 of books
23:11:19. 512 memory management [698: 46519] books with a price of 98.500000 were released
23:11:19. 512 memory management [698: 46519] Students of age 21 are released
The @ class keyword usually references a class in two ways. One is through # import, and the other is through @ class.
# The import method introduces all information in the header file.
@ Class only indicates that it is a class (if only one class is declared, # import is not used ).
# Import <Foundation/Foundation. h> @ class Book; // declare that Book is a class @ interface Student: NSObject {Book * _ book;} @ property int age; @ property Book * book;-(void) setBook :( Book *) book;-(id) initStudent :( int) age; @ end
In addition, the destructor in Student. m can be modified as follows:
// Destructor-(void) dealloc {self. book = nil; // call the setter method [_ book release]; NSLog (@ "the student whose age is % d has been released", _ age); [super dealloc];}
Self. book = nil; the setter method is called to release the object and set the attribute _ book of the Student Of the current class to nil.
@ Property parameter format: @ property (parameter 1, parameter 2,...) type name;
There are three main types of parameters:
Read/write attributes: readwrite/readonly
Setter processing: assign/retain/copy
Atomicity: atomic/nonatomic
Note:
Readonly indicates that only the getter method is generated. The default value is readwrite.
Assing default value (direct value assignment), copy is the old value of the setter method release, and then copy the new value
Atomic (default) ensures the atomicity of getter and setter, provides secure multi-thread access, and ensures high nonatomic performance. Therefore, nonatomic is generally selected.
# Import <Foundation/Foundation. h> @ class Book; // declare that Book is a class @ interface Student: NSObject // The assign parameter indicates that the set Method is assigned directly (default) // The getter method specifies the name of the getter method @ property (nonatomic, assign, getter = getStudentAge) int age; // The retain here indicates the old value of release, retain new value // (note that the retain parameter cannot be written for the basic data type) @ property (nonatomic, retain) Book * book;-(void) setBook :( Book *) book; -(id) initStudent :( int) age; @ end
# Import "Student. h "# import" Book. h "@ implementation Student // constructor-(id) initStudent :( int) age {if (self = [super init]) {_ age = age ;} NSLog (@ "student at % d created", _ age); return self ;}// destructor-(void) dealloc {self. book = nil; // call the setter method [_ book release]; NSLog (@ "the student whose age is % d has been released", _ age); [super dealloc];} @ end
The automatic release pool is an automatic memory recovery mechanism in OC. You can add some temporary variables to the automatic release pool to recycle and release them in a unified manner. When the pool is released automatically, all objects in the pool call the release method once. The OC object only needs to send an autorelease message and will add this object to the latest Auto Release pool (the release pool at the top of the stack ).
Autorelease only delays the call of release. For each autorelease operation, the system only puts this object into the current autorelease pool. When the pool is released, all objects in the pool call the release method once.
# Import "Student. h "# import" Book. h "@ implementation Student // create a static method constructor object + (id) student {Student * stu = [[[Student alloc] init] autorelease]; return stu ;} // create a static method object with parameters + (id) studentWithAge :( int) age {Student * stu = [self student]; stu. age = age; return stu;} // constructor-(id) initStudent :( int) age {if (self = [super init]) {_ age = age ;} NSLog (@ "student at % d created", _ age); return self ;}// destructor-(void) dealloc {self. book = nil; // call the setter method [_ book release]; NSLog (@ "the student whose age is % d has been released", _ age); [super dealloc];} @ end
Int main (int argc, const char * argv []) {// indicates creating an automatic release pool @ autoreleasepool {// first Writing Method Student * stu = [[[Student alloc] initStudent: 21] autorelease]; student * stu1 = [[Student alloc] initStudent: 21] autorelease];} // when brackets are over, the pool will be destroyed. // If the automatically released pool is destroyed, all objects in the pool call the release method @ autoreleasepool {// The Second Method Student * stu2 = [[Student alloc] initStudent: 21]; [stu2 autorelease];} @ autoreleasepool {// method 3 (recommended) // you do not need to manually release Student * stu3 = [Student student];} return 0 ;}