-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
一 、基本原理
Objective-c的内存管理机制与.Net/java那种全自动的垃圾回收机制是不同的,它本质上还是C语言的手动管理方式,只不过稍微加了些自动方法。
1、 Objective-c的对象生成之后,需要一个指针来指向它。
ClassA *class1 = [[ClassA alloc] init];
2、objective-c的对象在使用完成之后不会自动销毁,需要执行dealloc来释放空间(销毁),否则内存泄露。
autorelease pool原理剖析。
6.1 autorelease pool不是天生的,需要手动创立。只不过在新建一个iphone 项目时,xcode会自动帮你写好。autorelease pool的真名是NSAutoreleasePool.
6.2 NSAutoreleasePool 内部包含一个数组( NSMutableArray), 用来保存声明为autorelease的所有对象。
.3 NSAutoreleasePool 自身在销毁的时候,会遍历一遍这个数组,release 数组中的每个成员。如果此时数组中成员的retain count为1,那么release之后,retain count为0,对象正式被销毁。如果此时数组中成员的 retain count 大于1,那么 release之后,retain count大于0,此对象依然没有被销毁,内存泄露。列
int main (int argc, const char *argv[])
{
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
// do something
[pool release];
return (0);
}
所有标记为autorelease 的对象都只有在这个pool销毁时才被销毁。如果你有大量的对象标记为autorelease, 这显然不能很好的利用内存,在iphone这种内存受限的程序中很容易造成内存不足的。
int main(int agrc,char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int i,j;
for (i = 0; i < 100; i++)
{
for (j = 0; j < 10000; j++)
{
[NSString stringWithFormat:@"1234567890"];
}
}
[pool release];
return 0;
}
Objective-c程序中可以嵌套创建多个autorelease pool.在需要大量创建局部变量的时候,可以创建内嵌的autorelease pool 来及时释放内存。
int main(int agrc,char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int i,j;
for (i = 0; i < 100; i++)
{
NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];
for (j = 0; j < 10000; j++)
{
[NSString stringWithFormat:@"1234567890"];//
}
[loopPool release];
}
[pool release];
return 0;
}
set方法管理内存( @property管理的内存)
@property (retain) Book*book
@end
相当于
-(void)setBook:(Book*)book
{
if(_book!=book)
{
[ _book release];
//release旧值,retain新值
_book=[book retain];
}
}
@property参数分为以下四种:
(1) set方法内存管理的相关参数
retain : release旧值,retain新值(用于OC对象)
assign : 直接赋值,(默认,用于非OC对象类型
copy : release旧值,retain新值(一般用于NSString*)
(2) 控制需不需要生成set方法
readwrite : 同时生成set方法和get方法的声明和实现(默认)
readonly : 只会生成get方法的声明实现
(3)多线程管理
atomic:性能低(默认)
nonatomic:性能高
(4)控制set方法和get方法的名称
setter : 设置set方法的名称,方法名一定有个冒号:
getter : 设置get方法的名称(一般用在BOOL类型中)
总结
autorelease的好处
(1)不用关心对象释放的时间
(2)不用关心什么时候调用release
autorelease的坏处
(1)占用内存较大的对象不要随便使用autorelease
(2)占用内存较小的对象使用autorelease,影响不大
autorelease的常见错误
(1)alloc之后调用autorelease,又调用release
(2)连续调用多次autorelease