一、OC内存管理
1.内存分5大区域,其中两大区域是堆和栈;
栈:存放局部静态变量,存储空间不需要手动回收;
堆:存放动态产生的对象,需要进行内存管理释放空间;
2.内存“管理工具”——引用计数器
1、每个OC对象都有一个int类型引用计数器,表示“对象被引用的次数”。
2、引用计数器在对象内部占据4个字节的存储空间;
3、使用alloc、new或者copy创建新对象,对象引用计数器值为1;
4、当对象的引用计数器值为0时,对象所占内存被回收——这就是内存管理的条件;
5、对引用计数器的操作:
[对象名 retain]使对象计数器值+1;
[对象名 release]表示对象计数器-1;
[对象名retainCount]返回对象当前计数器值;
// 以下说明例子建立在类Person的基础上
@interface Person :NSobject
{
int _age;
Dog *_dog;
Cat *_cat;
Car *_car;
}
@end
3.alloc与release成对出现
1、只要调用了alloc创建对象,必须要有对象对用release——[对象名 release]应放在程序最后;
int main()
{
Dog *d = [[Dog alloc] init];
……
[d release];
return 0;
}
2、如果对象不是通过alloc产生的,就不需要release
int main()
{
NSString *s = @“jonh”;
……
return 0;
}
4.set方法的内存管理(代码格式固定)
1>基本数据类型:直接赋值,不需要管理内存;
- (void)setAge:(int)age
{
_age = age;
}
2>OC对象类型
- (void)setDog:(Dog *)dog
{
//1、先判断传入的对象是不是新的,如果传入的对象是旧的则不接收该对象
if ( dog != _dog)
{
//2、对旧对象做一次release,释放旧对象以便接收新对象
[_dog release];
//3、对新对象做一次retain
_dog = [dog retain];
}
}
5.dealloc方法的实现(当对象计数器值为0时系统自动调用,不能直接调用)
1>一定要有[super dealloc],而且必须放在最后面;
2>对self(当前)所拥有的所有其他对象做一次release
- (void)dealloc
{
[_car release];
[_cat release];
[_dog release];
[super dealloc];
}
6.@property 参数(@property只取代set和get方法的内存管理,但-(void)dealloc还是要保留)
1>OC对象类型
@property(nonatomic, retain) 类名 *属性名;
如:
@property (nonatomic, retain) Car *car;
@property (nonatomic, retain) id car;
//@property中被retain的属性,必须在dealloc方法中release该属性
-(void)dealloc
{
[_car release];
[super dealloc];
}
2>非OC对象类型(基本数据类型——int/float/enum/struct等)
@property (nonatomic, assign) 类型名称 属性名;
如:
@property (nonatomic, assign) int age;
7.autorelease
1、系统自带的方法不包含alloc、new、copy,则说明这些方法返回的对象都是经autorelease的
[NSString stringWithFormat:…];
[NSDate date];
2、开发中经常写一些类方法快速创建一个autorelease的对象
* 创建对象的时候不要直接使用类名,应用self
<span style="font-family:Microsoft YaHei, Helvetica Neue, SimSun;"><span style="font-size: 14px; line-height: 21px;">@interface Person :NSobject
@property (nonatomic, assign) int age;
+ (id)person;
+ (id)personWithAge:(int)age;
@end
#import "Person.h"
@implementation Person
+ (id)person
{
//创建对象的时候不要直接使用类名,应使用self
//return [[[Person alloc] init] autorelease];(当子类使用类方法快速创建对象时,将会出错)
return [[[self alloc] init] autorelease];
}
+ (id)personWithAge:(int)age
{
//类方法快速创建对象时不能用类名,用self
//Person *p = [[[Person alloc] init] autorelease];
//Person *p = [Person person];
Person *p = [self person];
p.age = age;
return p;
}
@end
#import
#import "Person.h"
@interface GoodPerson : Person
@property (nonatomic, assign) int money;
@end
#import
#import "Person.h"
#import "GoodPerson.h"
int main()
{
@autoreleasepool
{
//第一种方法
//Person *p = [[[Person alloc] init] autorelease];
//p.age = 100;
//第二种方法
//Person *p = [Person person];
//p.age = 100;
//第三种方法——创建对象的同时初始化
Person *p = [Person personWithAge:100];
GoodPerson *p1 = [GoodPerson personWithAge:10];
}
return 0;
}</span></span><span style="background-color: rgb(255, 255, 255);"><span style="font-size:18px;">
</span></span>
二、ARC内存管理
1、简介
1)、ARC是编译器特性,不是运行时特性也不是垃圾收集器,其与手动内存管理性能是一样的,代码书写更优化
2)、编译器自动在适当的地方插入适当的retain、release、autorelease语句。
2、基本原理
(1)、指针分两种:
1)、强指针:默认情况下,所有的指针都是强指针;
2)、弱指针:弱指针指向的对象被回收后,弱指针会自动变为nil指针,不会引发野指针错误。
(2)、ARC的判断准则:只要没有强指针指向对象,对象就会被释放。
3、特点
1)、不允许调用retain、release、autorelease、retainCount
2)、允许重写dealloc方法,但不能调用[super dealloc]
3)、@property参数
strong:成员变量是强指针,类似原来的retain(适用于OC对象)
weak:成员变量是弱指针(适用于OC对象)
assign:适用于非OC对象类型
4)、两端相互引用时,一端用strong、一端用weak