内存管理的两种方式:
1、MRR 手动管理
2.ARC 自动管理
两种内存管理常见的问题:
1、释放了或者重写了正在使用的数据 程序崩溃
2、没有释放不需要的对象 内存泄露
拥有权在实际操作中的体现:
MRR环境:
1、在某个代码块中创建的对象 代码块对其拥有权
-(void)test1{
NSString * t=[NSString new];
[t release]; //该代码块对t拥有拥有权 }
创建的关键字:alloc、new、mutablecopy、newobject、copy
对于无这些关键字的对象,系统对其有拥有权
不是自己创建的对象可以使用retain来获得拥有权
NSString *t=[@"jack" retain]; [t release];
属性声明拥有权可以使用retain和strong
@property(nonatomic,strong) NSString *tt;
2、
在某个类的头文件创建的对象
其拥有权是该类的某个对象的
@interface Person : NSObject //这个类的某个对象对copy的对象op拥有拥有权 @property(nonatomic,copy) NSString*op; @end
不再使用的对象应使用release 或者autorelease释放掉(谁创建谁释放 谁拥有谁释放)
-(NSString *)test2{ NSString *str=[[[NSString alloc]initWithString:@"小王"]autorelease]; //1.不行 还没返回就释放 返回值为nil //[str release]; return str; //2.return之后不再执行之后的代码 并没有释放 // [str release]; } -(void)test3{ NSString *str1=[self test2]; //3.不行 不是自己创建的对象就不能释放 // [str1 release]; }
使用dealloc释放掉一个对象所有的资源(当一个对象的引用计数为0 系统会自动调用dealloc去释放该对象的所有资源 以免内存泄漏)
该对象有一个属性name:
重写dealloc方法:
- (void)dealloc { //释放该对象对name的拥有权 [self.name release]; //调用父类方法 [super dealloc]; }
当两个类中的对象互相使用强引用 会造成循环引用 致使对象无法释放
//在头文件里面导入一个头文件 使用前向引用 @class
//在编译时没有真正导入
//必须在实现文件里面使用import导入
@class Page;
@property(nonatomic,strong) Page*pag;
@property(nonatomic,strong) Document *doc;
同样在page头文件中使用前向引用:@calss Ducument;
Page *pa=[Page new];//pa:retaincount = 1 Document *docu =[Document new];//docu:retaincount =1 pa.doc = docu;//docu:retaincount = 2; docu.pag=pa;//pa:retaincount = 2; [pa release];//retaincount =1 [docu release];//retaincount = 1 //由于pa docu始终存在相互引用的关系 且两者引用计数为一 均无法使用dealloc来释放彼此
此时 使用weak避免循环引用:
@property(nonatomic,strong) Page*pag;
@property(nonatomic,weak) Document *doc;
Page *pa=[Page new];//pa:retaincount = 1 Document *docu =[Document new];//docu:retaincount =1 pa.doc = docu;//docu:retaincount = 1; docu.pag=pa;//pa:retaincount = 2; [pa release];//retaincount =0 docu:retaincount= 1 [docu release];//retaincount = 0 //此时全部被释放