【语法】内存管理
内存管理原则
1.只要调用了alloc,new创建了一个新的对象,就需要调用一次release。
2.只要调用了retain(计数器+1)方法,也必须得做一次release。
3.不能操作已经被释放了的对象,这样会造成野指针错误。
4.只有对象存在,即计数器不为零,才能操作该对象。
内存设置野指针调试功能,如图,勾选
Diagnostics-Enable Zoombie Objects。
1.对象创建和销毁的标志就是对象的计数器是否为0,如果减少到0,就会调用系统的-(void)dealloc方法。
// alloc=>计数器=1 Person *p=[[Person alloc] init]; // 创建一个person对象p
// release=>计数器-1=0=>对象p将要被销毁,会调用系统dealloc方法 [p release]; // 有alloc 就必须得release
//如果dealloc方法内部写了方法 -(void)dealloc { NSLog(@"对象被销毁!"); }
//输出结果
2014-04-02 22:36:01.370 test[721:303] 对象被销毁!
2.【对象之间相互包含,内存管理】
例:一个Person类创建出了一个person对象,该对象拥有一只猫,就得在Person类中创建cat对象。
#import <Foundation/Foundation.h> #import "Cat.h" #import "Person.h" int main(int argc, const char * argv[]) { @autoreleasepool { Person *p=[[Person alloc] init]; // 创建一个Person对象p 【p的计数器=1】 Cat *c=[[Cat alloc] init]; // 创建一个Cat对象c 【c的计数器=1】 [p setCat:c]; // 将p调用setCat方法。形象的是p这个人拥有了c这只猫 [c release]; // 销毁这个c对象 【c的计数器=0】 [p release]; // 销毁这个p对象 【p的计数器=0】 } return 0; }
Person.h @interface Person : NSObject { Cat *_cat; } -(void)setCat:(Cat *)cat; -(Cat *)cat;
Person.m
-(void)setCat:(Cat *)cat { // 这表示的是我有一只新的猫来替换原先的猫,这样做就是1.先判断新的猫和旧的猫是不是同一只猫2.丢掉旧的猫【计数器减1】3.新的猫【计数器+1】赋值给_cat成员变量. if(cat!=_cat) { // 丢掉旧的猫 [_cat release]; // 对新的猫做一次retain 【形象一点就是retain后计数器+1,我支付了1块钱,买了这只新的猫】 _cat=[cat retain]; } } -(void)dealloc { [_cat release]; NSLog(@"Person被销毁了"); [super dealloc]; }
Cat.m
-(void)dealloc { NSLog(@"我的那只猫去世了!!!"); [super dealloc]; }
3.方法的简写
参照上面的代码中的setCat方法中的这个代码块
// Person.m
-(void)setCat:(Cat *)cat { if(cat!=_cat) { [_cat release]; //【1】 _cat=[cat retain]; //【2】 } }
等同于在Person.h中@property中使用@property(retain) Cat *cat;
// 这里的retain:生成set方法实现中,【1】release旧值,【2】retain新值 @property (retain) Cat *cat;