OC学习5——内存管理(上)
来源:互联网 发布:淘宝名字大全英文名 编辑:程序博客网 时间:2024/06/06 03:59
@一、范围:任何继承了NSObject的对象,对基本数据类型无效。
@二、原理:
1.每个对象内部都保存一个与之相关联的整数,称为引用计数器
2.当使用alloc、new或者copy创建一个对象的时候,对象引用计数器被设置为1
3.给对象发送一条retain消息,可以使引用计数器值+1
4.给对象发送一条release消息,可以使引用计数器值-1
5.当一个对象的引用计数器值为0时,那么它将被销毁,其占用的内存被系统回收,OC也会自动向对象发送一条dealloc消息。一般会重写dealloc方法,在这里释放相关资源。一定不要直接调用dealloc方法。
6.可以给对象发送retainCount消息活得当前的引用计数器值。
@三、管理规则:
1.谁创建,谁释放(谁污染,谁治理)。如果你通过alloc,new或(mutable)或copy来创建一个对象的话,那么你必须调用release或者autorelease。换句话说,不是你创建的你就不用释放。
2.一般来说,除了alloc,new,或者copy之外的方法创建的对象都被声明了autorelease。
3.谁retain,谁release。只要你调用了retain,无论这个对象啊是如何生成的,你都要调用release。
@四、示例
@interface Student : NSObject@property int age;@end上面是Student类的声明部分.h文件,下面是实现部分.m文件
@implementation Student@synthesize age = _age; // 在xcode4.5环境下可以省略- (void)dealloc { NSLog(@"%@被销毁了", self); [super dealloc]; // 一定要调用super的dealloc方法,而且最好放在最后面调用}@end我们写一个测试方法来说明内存引用计数的变化
Student *stu = [[Student alloc] init]; // 1 // z代表无符号 NSLog(@"count:%zi", [stu retainCount]); [stu retain]; // 2 NSLog(@"count:%zi", [stu retainCount]); [stu release]; // 1 NSLog(@"count:%zi", [stu retainCount]); [stu release]; // 0 // [stu release]; // 会发生野指针错误,也就是说访问了不属于你的内存再写一个示例说明:
// Student对象的计数器永远为1,所以不可能被释放 [[Student alloc] init].age = 10; [Student new].age = 10; // 上面的代码都有内存泄露
@五、对象之间的内存管理
对象之间的内存管理是经常见到的情况,我们来模拟一下学生(Student)和书(Book)之间的内存管理。首先Student类声明和实现部分如下:
@interface Student : NSObject { Book *_book;}@property int age;- (id)initWithAge:(int)age;@property Book *book;- (void)readBook;
@implementation Student#pragma mark - 生命周期方法#pragma mark 构造方法- (id)initWithAge:(int)age { if ( self = [super init] ) { _age = age; } return self;}#pragma mark 回收对象- (void)dealloc { // 释放Book对象 [_book release]; // [self.book release]; NSLog(@"student:%i 被销毁了", _age); [super dealloc];}#pragma mark - getter和setter// @synthesize book = _book;// 如果自己手动实现了getter和setter,xcode就不会自动生成@synthesize// 也就不会自动生成_book// getter和setter的默认实现- (void)setBook:(Book *)book { if (_book != book) { // 先释放旧的成员变量 [_book release]; // 再retain新传进来的对象 _book = [book retain]; }}- (Book *)book { return _book;}#pragma mark - 公共方法#pragma mark 读书- (void)readBook { NSLog(@"当前读的书是:%f", _book.price);}//#pragma mark - 私有方法//#pragma mark 私有方法1//- (void)test1 {}//#pragma mark 私有方法2//- (void)test2 {}//#pragma mark 私有方法3//- (void)test3 {}@endBook类的声明和实现部分如下:
@interface Book : NSObject@property float price; // 价格- (id)initWithPrice:(float)price;@end
@implementation Book- (id)initWithPrice:(float)price { if ( self = [super init] ) { _price = price; } return self;}- (void)dealloc { NSLog(@"book:%f 被销毁了", _price); [super dealloc];}@end
下面在main方法中对内存管理进行测试分析,示例如下:
void test(Student *stu) { // book:1 Book *book = [[Book alloc] initWithPrice:3.5]; // book:2 stu.book = book; // book:1 [book release]; // book:1 stu.book = book; stu.book = book; // book2:1 Book *book2 = [[Book alloc] initWithPrice:4.5]; // book2:2 stu.book = book2; // book2:2 stu.book = book2; // book2:1 [book2 release]; // book2:1 stu.book = book2;}void test1(Student *stu) { [stu readBook];}int main(int argc, const char * argv[]){ @autoreleasepool { // stu:1 Student *stu = [[Student alloc] initWithAge:10]; // stu:1 // book:1 // book2:1 test(stu); // stu:1 // book:1 // book2:1 test1(stu); // stu:0 // book2:0 // book:1 [stu release]; // stu = nil; 清空stu这个指针,stu就会变成空指针 // [stu release]; // 野指针(会报错) [nil release]; // 空指针(不会报错) } return 0;}通过分析,加深对内存管理的了解。熟记口诀,牢记原则。
0 0
- OC学习5——内存管理(上)
- OC学习笔记——内存管理
- OC学习笔记——内存管理
- oc学习笔记—内存管理
- OC学习--内存管理
- OC学习----内存管理
- OC——内存管理
- 黑马程序员——OC学习——内存管理
- OC学习6——内存管理(下)
- 黑马程序员——ios学习笔记 OC 内存管理
- 黑马程序员——oc加强学习(内存管理)
- 黑马程序员——OC语言学习——OC手动内存管理
- OC学习笔记之OC内存管理
- OC语言学习-内存管理
- OC内存管理学习感悟
- IOS学习 -- OC内存管理
- my学习OC--内存管理
- OC基础语法学习5:内存管理(手动管理)
- aop个人理解
- checkio -- Find Sequence
- 用C#做的一个简单的图片浏览器
- NYOJ 题目111 分数加减法
- 解析 Linux 中的 VFS 文件系统机制(根文件系统的由来)
- OC学习5——内存管理(上)
- DM8168 PWM驱动(寄存器设置)
- 框架搭建---文件目录结构
- 初探单例模式学习笔记
- ubuntu 13.10 安装 ia32-libs
- checkio -- Open Labyrinth python BFS的使用
- 虚数 计算圆形面积
- 面试中经典函数的实现
- WIN 64位VirtualBox安装Ubuntu 13.10,重启Ubuntu后黑屏