Objective-C basics 2: memory management basics,
1. Memory storage area
C, C ++. STACK: stores temporary variables and objects. Heap area: stores dynamically allocated objects. Static variable storage area: stores static variables and constant objects.
The memory storage area in OC is the same as that in C and C ++.
2. Why memory management?
All those who have written C and C ++ programs know that memory management is always a major pain point for C ++ programs. all crashes in projects come from memory-related operations, in particular, pointer operations and memory operations will cause program crashes if you do not pay attention to them. So how to manage the memory? I personally think there are the following principles: Try to use the encapsulated objects provided to us by the system instead of native objects, such as strings instead of char *, using string can avoid violations of most of the strings in the project; allocating on the stack is not distributed on the stack, and the automatic release function of the stack can help us release the stack; for complex memory operations such as multiple classes or threads referencing the same memory, add reference count to the memory. For memory operations, you must leave null.
We know that all objects in OC are dynamically allocated. How do we manage these objects in OC? The answer is to use the reference count for management.
3. Object Memory Management in OC
In OC, the reference count is used to manage the object lifecycle.
-(Instancetype) retain OBJC_ARC_UNAVAILABLE; // Add 1 TO THE REFERENCE
-(Oneway void) release OBJC_ARC_UNAVAILABLE; // subtract 1 from the reference
-(Instancetype) autorelease OBJC_ARC_UNAVAILABLE; // Automatically releases an object.
-(NSUInteger) retainCount OBJC_ARC_UNAVAILABLE; // returns the current reference Technology
When object B owns object A and Sets object A, it is better to use Retain to increase the reference count and reduce the reference Technology in the dealloc method.
Note that in the following code (void) setA: (A *) pAIn implementation
-(Void) setA: (A *) pAIn
{
[PAIn retain];
[PA release];
PA = pAIn;
}
Retain PAIn first, release PA, and assign values. This method can effectively avoid PAIn and PA pointing to the same object. Therefore, we strongly recommend that you write this method.
The Code is as follows:
@interface A : NSObject- (void) disInfo;@end@implementation A- (void) disInfo{ NSLog(@"I'm A haha!");}@end@interface B : NSObject{@private A* pA;}-(void) setA : (A*) pAIn;-(void) disA;@end@implementation B- (void)dealloc{ [pA release]; [super dealloc];}-(void) setA : (A*) pAIn{ [pAIn retain]; [pA release]; pA = pAIn;}-(void) disA{ [pA disInfo];}@endint main(int argc, const char * argv[]) { A* pA = [A new]; B* pB = [B new]; [pB setA:pA]; [pB disA]; [pB release]; [pA release]; return 0;}
In the above example, we need to manually drop the retain and release methods. That is to say, we need to know when retain and release are required, obviously, it takes a lot of time to track the problems caused by reference count in complex business logic. So, how can we make the object automatically retain and release? Anyone who has written a Windows Com program knows how OC works for CComPtr, a smart pointer class? As shown below.
4. automatically release memory in OC
In Cocoa, the automatic release pool @ autoreleasepool and the nsaid utoreleasepool are used together with the autorelease method of the object to automatically release the memory.
1) Use autoreleasepool and autorelease. The Code is as follows:
@autoreleasepool { A* pA = [A new]; [pA autorelease]; B* pB = [B new]; [pB autorelease]; [pB setA:pA]; [pB disA]; }
The above code has advantages over the code in 3: After pA and pB are created, the autorelease method is called directly to add the object to the automatic release function, and the code is compact, there is no need to worry about when to release later.
2) use the NSAID utoreleasepool and autorelease. The Code is as follows:
NSAutoreleasePool* pool = [NSAutoreleasePool new]; A* pA = [A new]; [pA autorelease]; B* pB = [B new]; [pB autorelease]; [pB setA:pA]; [pB disA]; [pool release];
The code is similar to the code using the keyword @ autoreleasepool.
Which of the following two methods should we choose? I personally think there are several principles:
1) Use @ autoreleasepool for code with compact object operations, because it is more efficient than the NSAID utoreleasepool.
2) object A has some example objects and these objects are kept in arrays such as NSArray. Use nutoreleasepool, because you only need to call the release method of nutoreleasepool in the dealloc object of, objects stored in NSArray are automatically released. Obviously, @ autoreleasepool does not have this capability.