Why do we need memory management? A warning is issued when memory is used up to 40M and 45M, and if not processed, the program is directly forced to shut down when the memory reaches 120M. So the flash-out is a logic error in the program, and it is possible that memory usage is too large.
(1) The process of creating an object: allocating memory space to store objects, initializing member variables, and returning pointers to objects.
(2) When the object is created, a reference counter Retaincount is created internally, and when retaincount=0, the system reclaims the current object, Retaincount is the only judgment tag. Release will -1,retain +1,retain after the return is self pointer.
(3) Turn the arc off into manual memory management mode.
(4) Memory pairing principle: If you have new, alloc, or retain, you need to pair a release or autorelease.
In Main.m, the @autorelease pool{} needs to be removed and managed entirely by hand:
#import <Foundation/Foundation.h> #import "Person.h" int main (int argc, const char * argv[]) { // Alloc retaincount=1 person *p1=[[person Alloc]init]; NSLog (@ "%lu", p1.retaincount); Reference count =2 [P1 retain]; NSLog (@ "%lu", p1.retaincount); Reference count =1 [P1 release]; NSLog (@ "%lu", p1.retaincount); Reference count =0 [P1 release]; How do I verify that the object has been destroyed at this time? Each object is destroyed when the Dealloc method is called, we rewrite dealloc, let it output something, prove that it is called to //rewrite is in the. m file of the class to which this object belongs, that is, the person.m in this example, return 0;}
In the PERSON.M:
#import "Person.h" @implementation person-(void) dealloc{ //Before the object is destroyed, release the related object in the parent class with the following statement [Super Dealloc]; NSLog (@ "I am Dealloc");} @end
(5) Once an object is recycled, this object is called a Zombie object, because Xcode does not always check for zombie objects, so when Cmd+r is running, accessing objects that have already been recycled can sometimes be an error. If you want Xcode to always check, the following settings. The default is not always checked, is to improve the efficiency of coding. However, it is recommended to close because it consumes memory when the class is larger than the project.
(6) The two problems of manual memory management research are: wild pointers and memory leaks. When the object is reclaimed and the pointer variable is not set to nil, the pointer is a wild pointer, which causes the program to flash back. So we usually set this pointer variable to nil after release. Although the subsequent use of P1, but the P1 is nil, send any message to it has no response and no impact, there will be no flash back.
(7) Memory leaks: The first case is that objects that are no longer being used are not recycled in memory. The second case is to accidentally set the pointer variable to nil before [P1 release]; it is invalid because Retaincount is a unique token, although no pointer is pointing to the object, but the object still exists in memory.
#import <Foundation/Foundation.h> #import "Person.h" int main (int argc, const char * argv[]) { // Alloc retaincount=1 person *p1=[[person Alloc]init]; NSLog (@ "%lu", p1.retaincount); Reference count =2 [P1 retain]; NSLog (@ "%lu", p1.retaincount); Reference count =1 [P1 release]; NSLog (@ "%lu", p1.retaincount); Reference count =0 [P1 release]; How do I verify that the object has been destroyed at this time? Each object is destroyed when the Dealloc method is called, we rewrite dealloc, let it output something, prove that it is called to //rewrite is in the. m file of the class to which this object belongs, that is, the person.m in this example, return 0;}
(8) After defining a P1 pointer variable, assigning it to another pointer variable P2, then the object retaincount unchanged, just one more P2 point to the object. Any P1 and P2 can release this object, and after release, these two pointer variables become wild pointers if they are not set to nil.
(9) When a pointer variable is passed as an argument to another method, it does not increase its reference count to the object. So in the final analysis whether there is no retain, new, alloc, and see if it is paired with release, Autorelease.
The Car class is a subclass of the person class, and there is a method for the man class-(void) Setcar: (Car *) Car{_car=car;} and-(void) Drive{[_car Run];},run method is the method of the car class. In the main function our person object P1 needs to be paired with a release when Alloc. If you need to use [P1 Drive], then you need to instantiate a car object car1, then you need to match a release for Car1. Generally, Car1 's alloc and release are wrapped in P1 's alloc and release. If I plan to [CAR1 release], and [P1 release], and then use any method of P1, such as [P1 Drive], found that because CAR1 has been release, so will be error. In other words, my P1 object still exists, but I can't use all of its methods any more. How to solve?
The first step: Modify the Setcar method to _car=[car retain], which is equivalent to the retaincount+1 of this Car1 object, so even if we use the pairing principle in the main function, Retaincount still has 1, so P1 can be used arbitrarily.
The second step: is to eliminate the car1 still exist above the retaincount of the 1, our goal is to this car1 Retaincount has been 1, unless my P1 is not, then car1 can not. So we need to eliminate it in the absence of P1, that is, in the P1 of the dealloc to eliminate it, the elimination is to put it [_car release];
(11) Answer the above question: If two car object variables car1 and CAR2 are defined consecutively within the main function, the memory of the last object variable is managed correctly, but the previous few are not normal. Because Car1 's retaincount still have 1, in dealloc inside of _car is car2, so car2 memory is normal, car1 is not normal, memory leaks. Solution?
The problem is to focus on Setcar, and add a sentence [_car release] in front of it; When the first call to _car is nil, does not affect, turns a circle out after Car1 's retaincount is 2, when the second call [_car release]; _car is car1, so Car1 is released, It then turns the car2 retaincount into 2, and then releases the CAR2 in the main function and Dealloc respectively.
(12) Answer the above question, if I call Setcar the second time to pass the CAR2, but still pass the time car1, then at the second call, encountered [_car release], then has released Car1, so the following sentence _car=[car retain]; It becomes a wild pointer operation. Solution?
Let's give this [_car release}; add a judgment statement. Because if there is no new object passed in the same object, _car is always the object, then we will be in the Dealloc [_car release], release, and if later passed the object and the last time, in the Dealloc [_car release ]; it becomes the second object is released, and the first object has one less release operation. So our conclusion is that if the new object being passed is the last one, it will not be released here, otherwise it will be released here. That is, if (_car!=car) {[_car release];_car=[car retain], the core of this sentence is release old value, retain new value. And if you pass the same object as the last time, then do nothing, Retaincount is still 1.
(13) So, summarize the member variable object memory management, is: a) mainly for setter method; b) Add an if (new value) in the Setter Method! = old value) {release old value, retain new value};c) and write a release in the Dealloc function of the class.
(14) In fact, when using @property to define member variables, different parameters are used to instruct the program to generate different types of setter methods. Retain is a setter method that instructs the program to generate memory management, which is the string above if. Assign is a common setter method, so we generally use retain for object types, and assign for basic data types.
However, the key is that the above retain just changed the setter method and did not automatically release it in Dealloc. So, while we're using @property (retain), although we don't need to rewrite the setter method, we need to rewrite the Dealloc method of the class to release the member variable once.
(15) by the way, thread management parameters Atomic is the residue of MAC development, General iOS is nonatomic, and to write, because the default is atomic, so there are generally only two forms @property (Nonatomic,retain) Char * Char1; and @property (nonatomic,assign) int age;
(16) by the way, ReadWrite (Generate getter and setter methods) and ReadOnly (Generate Getter method only), default is ReadWrite. The following statement can be used to replace the default setter or Getter Method name @property (nonatomic,assign,setter=abc) int age, and then call the setter method directly with ABC instead. This is generally used to change the name of the setter and getter when defining the bool variable, and is generally changed to isxxx.
"iOS Dev-33" Learn manual memory management temporarily abandon arc and retain/assign Knowledge--ios Engineer interview must test content