内存管理:针对创建和销毁过程进行管理
***************************
Student * s1 = [[
Student
alloc]
init];
[s1
release];
//0
销毁
NSLog( @"%lu",[s1 retainCount]); // 错误用法 , s1 现在时野指针 , 有原来的地址 但内存已被收回 钥匙 车
// 指针在栈区 , 指向的对象在堆区 ,retain 是对 对象操作的
Student * s2 = s1;
[s2 retain];
NSLog( @"%lu",[s1 retainCount]);
NSLog( @"%lu",[s1 retainCount]); // 错误用法 , s1 现在时野指针 , 有原来的地址 但内存已被收回 钥匙 车
// 指针在栈区 , 指向的对象在堆区 ,retain 是对 对象操作的
Student * s2 = s1;
[s2 retain];
NSLog( @"%lu",[s1 retainCount]);
//
当你对一个对象发送
autorelease
消息的时候
,
会把这个对象扔进
离它最近
的自动释放池中
,
当这个
池释放
的时候
,
会将池中管理的
对象逐一发送release消息
,
这时对象的引用计数才减
1
@autoreleasepool {
// 这就是一个自动释放池 ,{} 代表 pool 的开始和结束
//NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Student * s5 = [[ Student alloc] initWithName: @"liu" sex: @"n" age: 12];
[s5 sayHi];
[s5 autorelease];
//[pool release];
}
NSAutoreleasePool * pool1 = [[ NSAutoreleasePool alloc] init];
Student * stu1 = [[ Student alloc] init];
[stu1 autorelease];
[pool1 release];
@autoreleasepool {
// 这就是一个自动释放池 ,{} 代表 pool 的开始和结束
//NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Student * s5 = [[ Student alloc] initWithName: @"liu" sex: @"n" age: 12];
[s5 sayHi];
[s5 autorelease];
//[pool release];
}
NSAutoreleasePool * pool1 = [[ NSAutoreleasePool alloc] init];
Student * stu1 = [[ Student alloc] init];
[stu1 autorelease];
[pool1 release];
#import
<Foundation/Foundation.h>
// 头文件的交叉使用
// 继承 协议 是在 .h 中引用头文件
// 其他的在 .m 中引用 在 .h 中写 @Class : 类名
@class Student;
@interface MyClass : NSObject
// 释放 是 从子类到根类一级级释放
@property ( nonatomic, retain) Student * stu; // 逢 retain 重写 dealloc
@end
// 头文件的交叉使用
// 继承 协议 是在 .h 中引用头文件
// 其他的在 .m 中引用 在 .h 中写 @Class : 类名
@class Student;
@interface MyClass : NSObject
// 释放 是 从子类到根类一级级释放
@property ( nonatomic, retain) Student * stu; // 逢 retain 重写 dealloc
@end
自动释放池
的
工作原理
: 将一个
对象 扔进
离它
最近
的
释放池
中, 释放池
释放前
,对池中的
所有对象 逐一
发送
release
消息
: =当你对一个对象发送
autorelease
消息的时候
,
会把这个对象扔进
离它最近
的自动释放池中
,
当这个
池释放
的时候
,
会将池中管理的
对象逐一发送release消息
,
这时对象的引用计数才减
1
自动释放池 是:
建类
必备
MRC人工管理 或者 非ARC
ARC自动管理 Automatic Reference Counting
某个对象的
引用计数(有几个人在用)
alloc
0-1:retainCount 从0 变为 1
retain
+1:
retainCount + 1
copy
0 -1:
retainCount - 1
release
retainCount
马上-1
dealloc
标记删除,仅仅是指针指向的堆内存被销毁,但是指针保存的地址仍然存在,所以此指针将变为
野指针
autoRelease(自动释放)
retainCount
延迟 -1
dealloc方法 在
对象引用计数为0 的时候 自动调用,用于
释放自身
所占有的
资源
OC中
nil
(指向对象)是一个空指针 它可以调用任何方法都不会产生错误
属性,是retain 或者 copy 都要在最后进行释放
自动释放为:atuorelease
在
哪里
用到 alloc 就在哪里做
释放 (release)
#import "MyClass.h"
@implementation MyClass
- ( void)setStu:( Student *)stu
{
if ( _stu != stu) { // 旧值 不等 新值的时候
[ _stu release]; // 旧值 release
_stu = [stu retain]; // 新值 retain
// 或者
//_stu = [stu copy];
}
}
//重写父类 不用声明,自动调用
- ( void)dealloc
{
//NSLog(@"%@", self);
NSLog( @"MyClass");
//自己释放自己的,不 管父类的
[ _stu release]; //mc 中的对象 释放 对应的所有权
[ super dealloc];
}
@end
[
_name
release];
// 上边一行相当于下边一行
//[self.name release];
//self.name = nil;
//相当于下边两行代码,更安全
//[_name release];
//_name = nil;
// 上边一行相当于下边一行
//[self.name release];
//self.name = nil;
//相当于下边两行代码,更安全
//[_name release];
//_name = nil;
//
重写
setter
// 同时重写se tter 和 getter 时 , 系统 就不会帮我 们自动定义 _name 等实例变量
// 需要重新定义实例变量 , 或者加上 @synthesize age = _age;
// 同时重写se tter 和 getter 时 , 系统 就不会帮我 们自动定义 _name 等实例变量
// 需要重新定义实例变量 , 或者加上 @synthesize age = _age;
+ (
id)studentWithName:(
NSString *)name
sex:( NSString *)sex
age:( NSInteger)age
{
Student * stu = [[ Student alloc] initWithName:name sex:sex age:age];
[stu autorelease]; // 自动释放 便利构造器都需要自动释放
return stu;
// 或者
//return [[[Student alloc] initWithName:name sex:sex age:age] autorelease];
}
sex:( NSString *)sex
age:( NSInteger)age
{
Student * stu = [[ Student alloc] initWithName:name sex:sex age:age];
[stu autorelease]; // 自动释放 便利构造器都需要自动释放
return stu;
// 或者
//return [[[Student alloc] initWithName:name sex:sex age:age] autorelease];
}