iOS开发之OC内存管理(二)
来源:互联网 发布:孢子起源mac下载 编辑:程序博客网 时间:2024/06/06 12:55
在OC中也有一种内存自动释放的机制叫做“自动引用计数”(或“自动释放池”),与C#、Java不同的是,这只是一种半自动的机制,有些操作还是需要我们手动设置的。
自动内存释放使用NSAutoreleasepool声明一个自动释放池,如果一个对象在初始化时调用了autorelase方法,那么当代码块执行完之后,在块中调用过autorelease方法的对象都会自动调用一次release方法。这样一来就起到了自动释放的作用,同时对象的销毁过程也得到了延迟(统一调用release方法)。看下面的代码:
HXStudent.h
#import <Foundation/Foundation.h>#import "HXBook.h"@interface HXStudent : NSObject/** * 人名 */@property (nonatomic, copy) NSString *name;- (instancetype)initWithName:(NSString *)name;+ (instancetype)studentWithName:(NSString *)name;@end
HXStudent.m
#import "HXStudent.h"@implementation HXStudent- (instancetype)initWithName:(NSString *)name { if (self = [super init]) { _name = name; } return self;}+ (instancetype)studentWithName:(NSString *)name { HXStudent *student = [[[self alloc] init] autorelease];// 因为有alloc,所以要autorelease,遵循原则 student.name = name; return student;}- (void)dealloc { NSLog(@"销毁student,name = %@", _name); [super dealloc];}@end在main函数中:
int main(int argc, const char * argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; HXStudent *student1 = [[HXStudent alloc] init]; [student1 autorelease];// 因为有alloc,所有要autorelease student1.name = @"shx1";// 由于autorelease是延迟释放,所以这里仍然可以使用student1 HXStudent *student2 = [[[HXStudent alloc] initWithName:@"shx2"] autorelease];// 因为有alloc,所有要autorelease HXStudent *student3 = [HXStudent studentWithName:@"shx3"];// 内部已经调用了autorelease,所以不需要手动释放,这也符合内存管理原则,因为这里并没有alloc所以不需要release或者autorelease NSLog(@"在这里之前没有销毁上面三个对象"); // [pool drain];// 添加该行代码,会一个提示(double release) [pool release]; return 0;}
如果将断点打在NSLog一行,可以看到程序运行到这里,三个对象还没有被销毁(打断点只是为了观察)。当执行[pool release]完毕的时候,三个对象才会被销毁。因此上面person1,调用完autorelase之后它还存在,因此给name赋值不会有任何问题;在OC中通常如果一个静态方法返回一个对象本身的话,在静态方法中我们需要调用autorelease方法,因为按照内存释放原则,在外部使用时不会进行alloc操作也就不需要再调用release或者autorelase,所以这个操作需要放到静态方法内部完成。
注意:
对象并不是自动被加入到当前pool中,而是需要对对象发送autorelease消息,这样,对象就被加到当前pool的管理里了。
drain只是用于清除pool中对象,不会销毁池,release先调用drain方法清理对象,然后再释放自己内存。
对于自动内存释放简单总结一下:
autorelease方法不会改变对象的引用计数器,只是将这个对象放到自动释放池中;
自动释放池实质是当自动释放池销毁后调用对象的release方法,不一定就能销毁对象(例如如果一个对象的引用计数器>1则此时就无法销毁);
由于自动释放池最后统一销毁对象,因此如果一个操作比较占用内存(对象比较多或者对象占用资源比较多),最好不要放到自动释放池或者考虑放到多个自动释放池;
OC中类库中的静态方法一般都不需要手动释放,内部已经调用了autorelease方法。
管理内存遵循的原则:谁创建谁释放。
以上是在非ARC环境下的自动释放池的内存管理原理。
对于在ARC(自动引用计数)环境下,简单理解就是,系统会在适合的时候,自动帮我们调用retian、release操作,不用我们在手动写这些代码。
在ARC环境下声明自动释放池只需要使用@ autoreleasepool关键字的代码块就可以生产自动释放池,不用alloc。- iOS开发之OC内存管理(二)
- iOS 之OC内存管理(二)
- iOS开发之OC内存管理
- iOS开发之OC语法基础(四)--内存管理
- iOS开发之OC内存管理(一)
- iOS 之OC内存管理(一)
- IOS之OC内存管理
- iOS开发语言之OC 初级内存管理
- 黑马程序员------ios培训 oc内存管理(二)
- 自学iOS开发系列----OC(内存管理)
- ios开发-OC内存管理的学习
- iOS开发-Day20-OC 手动内存管理
- IOS开发笔记20-OC内存管理
- ios 开发 OC编程 内存管理
- IOS开发中的内存管理(二)
- IOS学习之OC内存管理
- OC内存管理二
- IOS OC 内存管理
- swift学习记录(函数)
- 欢迎使用CSDN-markdown编辑器
- 依赖注入(Dependency Injection)模式
- Linux权限——文件权限修改
- 生日悖论
- iOS开发之OC内存管理(二)
- iOS RTMP 视频直播开发笔记(6)- 封包 FLV
- hadoop再次集群搭建(3)-如何选择相应的hadoop版本
- 第13周项目3 算法验证—Floyd算法
- Linux环境变量的设置和查看
- 快速判断素数
- fedora下手动编译安装vim
- Go语言把IP转为int存储.节省空间提高索引速度
- Entity Framework 全面教程详解(转)