15 手动内存管理
来源:互联网 发布:呜呼与嗟乎的意思 编辑:程序博客网 时间:2024/05/16 15:47
15 手动内存管理
Tags: Objective-C
XCode5以前,对象的内存管理都需要手动管理,后来有了ARC之后才不需要手动管理,但是理解手动内存管理有助于我们编写更高效率的代码。
对象的引用计数规则:
1. 当调用以alloc、new、copyXXX、mutableCopyXXX名字开头的方法创建对象时,对象的引用计数加1。
2. [objectPointer retain]
对象的引用计数加1,然后返回对象本身。
3. [objectPointer release]
对象的引用计数减1。
4. [objectPointer autorelease]
将对象添加到自动释放池中,不改变对象的引用计数。
5. [objectPointer retainCount]
返回对象的引用计数的值。
6. 对象的引用计数为0时,会调用该对象继承自NSObject的重写的dealloc方法,方法内会释放对象所持有的其它对象(通常是调用被持有对象的release方法将引用计数减1),最后调用[super dealloc]方法。
7. 谁为对象添加引用计数,就要在退出前将对象的引用计数减1,也成为谁retain谁release,通常retain release是对称的。
自动释放池:
存放对象的容器(如NSMutableArray集合,每个元素是一个对象的指针),将对象添加到自动释放池就是将对象添加到NSMutable集合中,而NSAutoreleasePool
类又重写了release
方法(依次调用集合中的每个对象的release方法)。NSAutoreleasePool
对象本身也有引用计数,当调用[NSAutoreleasePool对象 release]
时候,NSAutoreleasePool对象的引用计数变为0然后调用dealloc方法,先回收池中所有的对象然后回收释放池。
1. [NSAutoreleasePool对象 release]
:不仅回收释放池内的对象然后还回收释放池。
2. [NSAutoreleasePool对象 drain]
:只回收释放池内的对象不回收释放池。
本文所有的代码工程都需要关闭ARC,因为在XCode7上,ARC是自动开启的,我们需要手动内存管理,就需要将Objective-C Automatic Reference Counting设置为NO,关闭方法下图:
代码示例:
GKHItem.h
#import <Foundation/Foundation.h>@interface GKHItem : NSObject@end
GKHItem.m
#import "GKHItem.h"@implementation GKHItem//重写init方法- (id) init { if (self = [super init]) { NSLog(@"init方法中,引用计数为:%ld", self.retainCount); } return self;}//重写delloc方法- (void) dealloc { NSLog(@"系统开始销毁GKHItem对象了,再见!"); [super dealloc];}@end
GKHUser.h
#import <Foundation/Foundation.h>#import "GKHItem.h"@interface GKHUser : NSObject { GKHItem *_item;//定义GKHUser持有GKHItem对象}- (void) setItem:(GKHItem *)item;- (GKHItem *) item;@end
GKHUser.m
#import "GKHUser.h"@implementation GKHUser- (void) setItem:(GKHItem *)item { if (_item != item) { [_item release];//_item本来持有的对象的引用计数-1 _item = [item retain];//item持有的对象引用计数+1,并赋给_item }}- (GKHItem *) item { return _item;}//重写delloc方法- (void) dealloc { [_item release];//持有的GKHItem对象引用计数-1 NSLog(@"系统开始销毁GKHUser对象"); [super dealloc];}@end
MRCTest.m
#import <Foundation/Foundation.h>#import "GKHUser.h"int main(int argc, const char * argv[]) { GKHItem *item = [GKHItem new]; NSLog(@"item的引用计数为:%ld", item.retainCount); GKHUser *user = [[GKHUser alloc] init]; [user setItem:item]; NSLog(@"被GKHUser对象持有后,item的引用计数为:%ld", item.retainCount); GKHItem *item2 = [GKHItem new]; [user setItem:item2]; NSLog(@"item的引用计数为:%ld", item.retainCount);//1 NSLog(@"item2的引用计数为:%ld", item2.retainCount);//2 NSLog(@"user的引用计数为:%ld", user.retainCount);//1 [item dealloc]; [user dealloc]; [item2 dealloc]; return 0;}@end
MRCTest.m的运行结果如下:
init方法中,引用计数为:1
item的引用计数为:1
被GKHUser对象持有后,item的引用计数为:2
init方法中,引用计数为:1
item的引用计数为:1
item2的引用计数为:2
user的引用计数为:1
系统开始销毁GKHItem对象了,再见!
系统开始销毁GKHUser对象
系统开始销毁GKHItem对象了,再见!
NSAutoReleasePoolTest.m
#import <Foundation/Foundation.h>#import "GKHItem.h"#import "GKHUser.h"GKHItem * productItem() { GKHItem *item = [GKHItem new];//引用计数为1 return [item autorelease];//将item对象添加到自动释放池}int main(int argc, const char * argv[]) { //创建自动释放池 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GKHItem *it = productItem();//it的引用计数为1 GKHUser *ur = [[GKHUser alloc] init];//创建GKHUser对象ur [ur setItem:it];//ur持有it [ur autorelease];//将ur添加到自动释放池 NSLog(@"it的引用计数为:%ld", it.retainCount);//it的引用计数为2 NSLog(@"ur的引用计数为:%ld", ur.retainCount);//ur的引用计数为1 GKHItem *it2 = [[[GKHItem alloc] init] autorelease]; NSLog(@"it2的引用计数为:%ld", it2.retainCount);//it2的引用计数为1 GKHItem *it3 = [[[GKHItem alloc] init] autorelease]; NSLog(@"it3的引用计数为:%ld", it3.retainCount);//it3的引用计数为1 [pool release];//释放池的引用计数为0后,释放其中的所有对象,释放的顺序跟添加的顺序相反 return 0;}
NSAutoReleasePoolTest.m运行结果如下:
it的引用计数为:2
ur的引用计数为:1
init方法中,引用计数为:1
it2的引用计数为:1
init方法中,引用计数为:1
it3的引用计数为:1
系统开始销毁GKHItem对象了,再见!
系统开始销毁GKHItem对象了,再见!
系统开始销毁GKHUser对象
系统开始销毁GKHItem对象了,再见!
- 15 手动内存管理
- 8,手动内存管理
- 手动内存管理
- iOS手动内存管理
- OC-手动内存管理
- 手动进行内存管理
- golang手动管理内存
- 手动内存管理方法
- 内存管理之手动管理
- Objective-C手动内存管理
- OC中手动管理内存
- OC手动内存管理注意事项
- OC的手动内存管理
- iOS笔记-手动内存管理
- (iOS)手动内存管理01
- ios之手动内存管理
- iOS之手动内存管理
- iOS之手动内存管理
- 11 类别(category)和扩展(extension)
- 12 协议
- 13 异常
- UVALive 6926Maximum Score(组合数学)
- 14 反射
- 15 手动内存管理
- 16 Foudation框架之NSString和NSMutableString
- 17 Foundation框架之NSDate、NSDateFormatter、NSDateComponents、NSCalendar、NSLocale、NSTimer
- 18 对象的copy与mutableCopy方法
- 19 NSCopying与NSMutableCopying协议+深复制和浅复制
- Java --- 就业指导
- Github的使用
- 广播
- ScrollView代理和NSTimer