手动内存管理和自动释放池
2015-03-11 22:33
225 查看
手动内存管理
在进行内存管理的时候要注意内存管理的准则:谁开辟内存,谁释放内存(谁污染的谁治理) 。开辟内存之后,对象的引用计数为1,只有继承自NSObject的对象才有内促管理的概念, 当对象引用计数为0的时候对象的内存会被清理。
下列关键字会开辟内存,对象引用计数器+1
allocnew
copy
mutableCopy
下列是内存管理的相关方法。
retain :保留对象,对象的引用计数器+1。release : 释放对象,对象引用计数器-1。
retainCount : 获取对象当前的引用数。
autorelease : 将对象托管到自动释放池。
dealloc : 对象释放之前调用的方法,由系统自动调用,不能主观调用。
直赋值接指针和retain的区别
Person *p = [[Person alloc] init];
//指针赋值并不会让对象的引用计数器+1
Person *p2 = p ;
// 输出p2 retainCount = 1, p retainCount = 1
NSLog(@"p2 retainCount = %lu , p retainCount = %lu",[p2 retainCount],[p retainCount]) ;
// retain 会让引用计数器+1
Person *p3 = [p retain] ;
// 输出2,2,2
NSLog(@"p3 retainCount = %lu,p2 retainCount = %lu , p retainCount = %lu",[p3 retainCount],[p2 retainCount],[p retainCount]) ;
// 释放对象,谁污染的谁治理
[p release] ; // 引用数量变为1
// 释放对象
[p3 release] ; // 引用数量变为0 , 调用对象dealloc方法
//[p2 release] ; // 这句报错,因为所指向的对象已经被释放掉了
[/code]
直接指针赋值并不会让引用计数器+1
retain(保留)会使引用计数器 +1 .
AutoReleasePool 自动释放池
在开发过程中,某些对象可能并不能立马释放掉,可以暂时将这个对象托管进当前上下文中的自动释放池,以便最后统一释放。// 创建自动释放池
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Person * p = [[Person alloc] init];
// 添加到自动释放池
[p autorelease] ;
// 自动释放,其中托管的对象也会被释放
[pool release] ;
[/code]
AutoReleasePool 和 @autoreleasepool {}
@autoreleasepool {} 是NSAutoreleasePool 的另一种写法,'{}' 内的代码就是在一个NSAutoreleasePool 中。@autoreleasepool{
} // 相当于系统自动创建NSAutoreleasePool 自动在结尾处让这个pool release.
[/code]
多个NSAutoreleasePool嵌套
程序中可以嵌套多个自动释放池,autorelease 的对象托管在对象代码所在的释放池。NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];
Person *p1 = [Person new];
// 被托管在pool1 中
[p1 autorelease] ;
NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init];
Person *p2 = [Person new];
// 被托管 在 pool2中
[p2 autorelease];
[pool2 release] ;
[pool1 release] ;
[/code]
事件循环和内存分配
在开发IOS程序的时候,处理一个按钮的单击事件会调用单击响应的方法,系统会创建一个新的自动释放池给这个响应方法使用,当这个事件处理方法结束后系统就会release创建的自动释放池,由于事件可以多次循环发生,每一次发生系统都会创建一个针对于当前事件的自动释放池,事件处理完毕后释放这个自动释放池。我们可以使用retain来保存对象不被事件自动创建的自动释放池清理.系统API中的对象大多是被自动释放池托管的,所以我们无需关心这些对象的释放。
-(void) onClick {
// 在事件方法结束后data 所指向的内存块默认会被清理,为了保留下来data 对象,我们使用了retain关键字.
data = [[NSMutableArray array] retain] ;
}
[/code]
属性对象的释放问题。
当一个累的属性是另一个对象的指针时,我们可以重写dealloc方法来释放属性对象。@implementation Person
{
// 是指针 , 存在于内存中。
NSObject *obj ;
}
// 重写父类的dealloc 方法
- (void)dealloc
{
NSLog(@"test") ;
// 释放属性
[obj release] ;
// 注意:必须写上这一句,释放父类的资源
[super dealloc] ;
}
@end
[/code]
// 引入Person 类
#import "Person.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Person *p = [Person new] ;
// p release 的时候会调用dealloc 方法,释放Person类自身的属性.
[p release] ;
}
return 0;
}
[/code]
属性的参数 : retain 和 assign
@property(assign) NSObject *obj ;retain
retain 属性合成的setter 保留一下再赋值,引用计数器+1-(void)setObjA:(ClassA *)a
{
If(objA != a)
{
[objA release];
objA = [a retain];//对象的retain count 加1
}
}
[/code]
assign (默认)
assign 属性合成的setter直接赋值,引用计数器不会+1-(void)setObjA:(ClassA *)a
{
objA = a;
}
[/code]
相关文章推荐
- OC-027.手动内存管理中的自动释放池@autorelease
- OC手动内存管理-使用自动释放池
- OC手动内存管理-自动释放池的销毁时机与工作过程
- OC手动内存管理-临时对象与事件循环中的自动释放池
- 移动开发:iOS内存管理之:引用计数、ARC、自动释放池autoreleasepool和便捷方法之间的关系
- objective-C 的内存管理之-自动释放池(autorelease pool)
- 七十三、基础框架(三十一)内存管理-自动释放池
- OC_语法入门_day5_内存管理_计数器/set方法/property的参数/循环引用/自动释放池
- iOS arc(自动释放)和mrc(手动释放)下重写set方法
- 关于@autoreleasepool的性能测试及手动释放自动释放池
- linux内存管理及手动释放机制
- iOS内存管理之:引用计数、ARC、自动释放池autoreleasepool和便捷方法之间的关系
- MRC内存管理(三)autorelease自动释放
- iOS内存管理之:引用计数、ARC、自动释放池autoreleasepool和便捷方法之间的关系
- 内存管理之自动释放池
- iOS 自动释放手动释放混编
- autorelease pool的内存管理之-自动释放池
- 七十七、基础框架(三十五)内存管理-一个关于自动释放池的示例
- OC--内存管理之自动释放,[NSMutableArray array]生成的自动释放数组被自动释放后引起的严重后果
- Object-C内存管理---资源自动释放池(The Autorelease Pool)