IOS内存管理总结
2013-10-17 18:06
246 查看
IOS 内存管理模型
Objcective-C三种内存管理方式:
1:MRR (ManualRetain-Release): 手工持有-释放 方式
2 : ARC(Automatic Reference Counting): 自动引用计数
3: GC (GarbageCollection) : 垃圾回收; 只适用于 MAC OS, 不能使用于 ios。
调试内存工具:
xcode自带的 Clang Static Ananlyzer. --- 编译期
技术文章:TN2239, IOS Debugging Magic (NSZombie来发现release 过多的对象)
Instruments —— Viewing and Analyzing TraceData
内存管理策略:
ios中对于内存管理是基于“对象所有权”来维护的,
通过alloc , new, copy,mutableCopy开头创建的对象,那么这个对象就是拥有所有权。
retain–
引用计数加 1;
release-引用计数减1;
直到为0, 就会触发 dealloc() 函数,该函数是由系统调用,我们不能调用;在该函数中要记住调用[super dealoc];
retain 方式是一种强引用方式,
为了避免父子对象间形成retain-cycle 现象:cocoa规定:父对象可以拥有子对象的强引用,而子对象只能拥有父对象的弱引用。
弱引用常见表现形式及注意事项:
1:NotificationCenter,注意当不需要的时候,需要将消息的注销。
2:delegate,当不需要需要将其设为空。
以免dealloc后,还在给其发送引发程序崩溃。
autorelease 和 release
区别:
release:立即释放内存
autorelease:不立即释放内存,那是在什么时候执行呢?
每一个线程都至少有一个AutoreleasePool,管理着autorelease对象,相当于一个autorelease对象容
器,AutoreleasePool之间是一种“后进先出”方式的栈结构,当AutoreleasePool被dealloc的时候,
他就会去给容纳的每一个对象发送release消息为。 而系统什么时候调用AutoreleasePool的dealloc
呢?就是在调用其release 或 drain的时候(在ARC或MRR中,调用release,但是在Mac OS中
(或垃圾回收)中应该调用drain而不是 release, 垃圾回收中, release什么都不做)
为了理解AutoreleasePool是一个栈的形式,请参见一下代码:
– (id)findMatchingObject:(id)anObject {
id match = nil;
while (match == nil) {
NSAutoreleasePool*subPool = [[NSAutoreleasePool alloc] init];
NSError *error = nil;
NSString *fileContents = [[[NSString alloc]initWithContentsOfURL:url
encoding:NSUTF8StringEncoding
error:&error]autorelease];
[fileContents retain];
[subPooldrain];
}
return [match autorelease]; /* Let match go and return it. */
}
在函数的内部产生了一个subPool名字的autoreleasePool,他就进入了栈顶,然后subPool drain调用后,这个autoreleasePool就弹出了,这个池就销毁了,其间的fileContents如果没有在后面retain,那么也就会跟随subPool的销毁而销毁。通过调用retain,延长其生命期至栈的下一个AutoreleasePool。
如果drain的这个池不是栈顶,会怎么样?
如果你 drain 一个池,但是这个池却不在栈顶,那么栈内位于它上面的所有池就都 drain 了(这 意味着所有他们容纳的对象,都收到 release 消息)。如果你不小心忘记了调用一个池的 drain,那 么从嵌套结构上看,更外一层的池在 drain 的时候,会销毁这个池。ji
典型例子代码:
1:release
{
Person *per = [[Persion alloc]init];
NSString *name = per.fullName;
[per
release];
}
2: autorelease
-(NSString*)fullName{
NSString *string = [[[NSString alloc]initWithFormat:@”%@”, self.lastname]autorelease];
return string;
}
允许其调用者来使用该对象。
3: 没有所有权,但是可以提供给调用者直接使用。
-(NSString*) fullName{
NSString *string = [NSStringstringWithFormat:@”%@”, self.lastName”];
return string;
}
通过stringWithFormat返回的string没有所有权,方法调用者可以直接使用放回的数据
4:所有权不会通过函数返回而传递(这是我自己起的)。
-(NSString*)fullName {
NSString *string = [NSString alloc]initWithFormat:@”%@”, self.lastName];
return string;
}
导致内存泄漏,方法的调用者没有理由来release这个返回的string.
进程退出与dealloc 关系:
进程的内存会在退出时自动回收,当应用退出的时候,对象可能接收不到dealloc这样的消息。
不明白的地方:
不能把资源管理的职能交给 dealloc,那么会暴露好多问题,比如:
(我只能这样理解,对象与资源的生命周期时不一样的。所以不能放在对象的dealloc中处理,至于下面的问题,还需要再琢磨一下)
1. 对象图的拆除顺序问题
实际上,对象图的拆除是没有任何顺序保证的。也许你认为、你希望有一个具体明确 的顺序,但事实是没有。如果对象被放到了 autorelease 池,这个拆除的过程也会发生变化,并导致你无法预见的后果。
2. 系统稀缺资源不能回收
内存泄露问题,是系统的缺陷,应该被修正。但问题是通常这个问题不是立刻暴露出 来的。如果没有保留的时候,你认为某个资源已经释放,而实际上没有释放,你就会面临 更加严重的问题了。比如,如果文件句柄被用光了,其结果将是你无法保存数据。
3. 释放资源的操作由其他线程来做
如果对象在一个不确定的时刻被放到了 autorelease池中,它将被线程池中的线程来 dealloc。这对于有些只能供单一线程来访问的资源而言,是致命的错误。
Objcective-C三种内存管理方式:
1:MRR (ManualRetain-Release): 手工持有-释放 方式
2 : ARC(Automatic Reference Counting): 自动引用计数
3: GC (GarbageCollection) : 垃圾回收; 只适用于 MAC OS, 不能使用于 ios。
调试内存工具:
xcode自带的 Clang Static Ananlyzer. --- 编译期
技术文章:TN2239, IOS Debugging Magic (NSZombie来发现release 过多的对象)
Instruments —— Viewing and Analyzing TraceData
内存管理策略:
ios中对于内存管理是基于“对象所有权”来维护的,
通过alloc , new, copy,mutableCopy开头创建的对象,那么这个对象就是拥有所有权。
retain–
引用计数加 1;
release-引用计数减1;
直到为0, 就会触发 dealloc() 函数,该函数是由系统调用,我们不能调用;在该函数中要记住调用[super dealoc];
retain 方式是一种强引用方式,
为了避免父子对象间形成retain-cycle 现象:cocoa规定:父对象可以拥有子对象的强引用,而子对象只能拥有父对象的弱引用。
弱引用常见表现形式及注意事项:
1:NotificationCenter,注意当不需要的时候,需要将消息的注销。
2:delegate,当不需要需要将其设为空。
以免dealloc后,还在给其发送引发程序崩溃。
autorelease 和 release
区别:
release:立即释放内存
autorelease:不立即释放内存,那是在什么时候执行呢?
每一个线程都至少有一个AutoreleasePool,管理着autorelease对象,相当于一个autorelease对象容
器,AutoreleasePool之间是一种“后进先出”方式的栈结构,当AutoreleasePool被dealloc的时候,
他就会去给容纳的每一个对象发送release消息为。 而系统什么时候调用AutoreleasePool的dealloc
呢?就是在调用其release 或 drain的时候(在ARC或MRR中,调用release,但是在Mac OS中
(或垃圾回收)中应该调用drain而不是 release, 垃圾回收中, release什么都不做)
为了理解AutoreleasePool是一个栈的形式,请参见一下代码:
– (id)findMatchingObject:(id)anObject {
id match = nil;
while (match == nil) {
NSAutoreleasePool*subPool = [[NSAutoreleasePool alloc] init];
NSError *error = nil;
NSString *fileContents = [[[NSString alloc]initWithContentsOfURL:url
encoding:NSUTF8StringEncoding
error:&error]autorelease];
[fileContents retain];
[subPooldrain];
}
return [match autorelease]; /* Let match go and return it. */
}
在函数的内部产生了一个subPool名字的autoreleasePool,他就进入了栈顶,然后subPool drain调用后,这个autoreleasePool就弹出了,这个池就销毁了,其间的fileContents如果没有在后面retain,那么也就会跟随subPool的销毁而销毁。通过调用retain,延长其生命期至栈的下一个AutoreleasePool。
如果drain的这个池不是栈顶,会怎么样?
如果你 drain 一个池,但是这个池却不在栈顶,那么栈内位于它上面的所有池就都 drain 了(这 意味着所有他们容纳的对象,都收到 release 消息)。如果你不小心忘记了调用一个池的 drain,那 么从嵌套结构上看,更外一层的池在 drain 的时候,会销毁这个池。ji
典型例子代码:
1:release
{
Person *per = [[Persion alloc]init];
NSString *name = per.fullName;
[per
release];
}
2: autorelease
-(NSString*)fullName{
NSString *string = [[[NSString alloc]initWithFormat:@”%@”, self.lastname]autorelease];
return string;
}
允许其调用者来使用该对象。
3: 没有所有权,但是可以提供给调用者直接使用。
-(NSString*) fullName{
NSString *string = [NSStringstringWithFormat:@”%@”, self.lastName”];
return string;
}
通过stringWithFormat返回的string没有所有权,方法调用者可以直接使用放回的数据
4:所有权不会通过函数返回而传递(这是我自己起的)。
-(NSString*)fullName {
NSString *string = [NSString alloc]initWithFormat:@”%@”, self.lastName];
return string;
}
导致内存泄漏,方法的调用者没有理由来release这个返回的string.
进程退出与dealloc 关系:
进程的内存会在退出时自动回收,当应用退出的时候,对象可能接收不到dealloc这样的消息。
不明白的地方:
不能把资源管理的职能交给 dealloc,那么会暴露好多问题,比如:
(我只能这样理解,对象与资源的生命周期时不一样的。所以不能放在对象的dealloc中处理,至于下面的问题,还需要再琢磨一下)
1. 对象图的拆除顺序问题
实际上,对象图的拆除是没有任何顺序保证的。也许你认为、你希望有一个具体明确 的顺序,但事实是没有。如果对象被放到了 autorelease 池,这个拆除的过程也会发生变化,并导致你无法预见的后果。
2. 系统稀缺资源不能回收
内存泄露问题,是系统的缺陷,应该被修正。但问题是通常这个问题不是立刻暴露出 来的。如果没有保留的时候,你认为某个资源已经释放,而实际上没有释放,你就会面临 更加严重的问题了。比如,如果文件句柄被用光了,其结果将是你无法保存数据。
3. 释放资源的操作由其他线程来做
如果对象在一个不确定的时刻被放到了 autorelease池中,它将被线程池中的线程来 dealloc。这对于有些只能供单一线程来访问的资源而言,是致命的错误。
相关文章推荐
- ios开发内存管理及内存泄漏整理总结
- 【IOS 开发学习总结-OC-24】★★★objective-c——内存管理
- iOS开发经验总结—内存管理
- 黑马程序员之ios学习总结——11 OC语言的内存管理1
- iOS的内存管理机制总结
- ios开发中内存管理总结
- 【iOS7的一些总结】5、iOS中的内存管理
- 对iOS开发中内存管理的一点总结与理解
- IOS ARC内存管理总结
- iOS中引用计数内存管理机制分析总结(NSString引用计数为-1的情况)
- 总结一下iOS中内存管理
- 黑马IOS学习总结1--内存管理
- 黑马程序员_ios基础总结10_内存管理
- iOS内存管理小总结
- IOS内存管理知识总结【转】
- iOS ARC内存管理总结
- ios经典面试题总结--内存管理
- iOS经典面试题总结--内存管理
- 黑马程序员_IOS内存管理学习总结(三)
- iOS开发内存管理总结