内存管理:针对创建和销毁过程进行管理
***************************
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
//同时重写setter和getter时,系统就不会帮我们自动定义_name 等实例变量
//需要重新定义实例变量,或者加上 @synthesize age = _age;
//同时重写setter和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];
}