iOS内存管理的思考方式
自己生成的对象,自己持有。
非自己生成的对象,自己也能持有。
不再需要自己持有的对象时释放。
非自己持有的对象无法释放。
iOS内存管理网上有很多资料,大家可以去查,我就在这里说一下会注册到autoreleasePool的情况,任何注册autoreleasePool都会讲对象注册到最近的autoreleaserPool中。
1,ARC无效的情况下,即MRC情况下常规方法:
id obj = [[NSObject alloc] init];
[obj autorelease];
此方法在ARC会用到,初学者要理解内存管理会接触到。
2,使用以alloc/new/copy/mutableCopy开头以外的方法即不使用此类方法,生成并持有对象如类方法创建对象。
//非ARC下 如:使用[NSMutableArray array]取得对象的存在,但自己不持有对象如何实现
- (id)object{
id obj = [[NSObject alloc] init]; //自己持有对象
[obj autrelease];
return obj;
}
3,ARC使用__autoreleasing 修饰符
@autoreleasePool{
id __autoreleasing obj = [[NSObject alloc] init];
}
使用“@autoreleasePool块” 来替代“NSAutoreleasePool类对象生成、持有以及废弃”这一范围。
ARC下 使用__autoreleasing修饰的变量来替代调用autorelease方法,注册到autoreleasePool中。
4,ARC还有一种可以注册到autoreleasePool中即使用__weak修饰符修饰的变量也会讲对象注册到autoreleasePool中。
{
id __weak o = obj;
NSLog{@"1%@",o};
NSLog{@"2%@",o};
NSLog{@"3%@",o};
NSLog{@"5%@",o};
}
输出autoreleasePool中的资源
objc[1511]: ##############
objc[1511]: AUTORELEASE POOLS for thread 0x10bc8d000
objc[1511]: 19 releases pending.
objc[1511]: [0x7f8cf4800000] ................ PAGE (hot) (cold)
objc[1511]: [0x7f8cf4800050] ################ POOL 0x7f8cf4800050
objc[1763]: [0x7fd8c40000a8] 0x7f8cf3744700 NSObject
objc[1763]: [0x7fd8c40000b0] 0x7f8cf3744700 NSObject
objc[1763]: [0x7fd8c40000b8] 0x7f8cf3744700 NSObject
objc[1763]: [0x7fd8c40000c0] 0x7f8cf3744700 NSObject
objc[1511]: [0x7f8cf48000c8] 0x7f8cf3744700 NSObject
objc[1511]: ##############
相应的变量o的对象会注册到autoreleasePool中5次。 而这样的注册到autoreleasePool中操作会消耗相应的CPU资源。(使用__weak本身也会有其他方面的资源消耗会在介绍修饰符的博客中讲到)未来避免此类情况可以将__weak修饰的变量赋值给带有__strong修饰符的变量。如下
{
id __weak o = obj;
id tmp = o;
NSLog{@"1%@",o};
NSLog{@"2%@",o};
NSLog{@"3%@",o};
NSLog{@"5%@",o};
}
这样仅会注册到autoreleasePool中1次。
objc[1763]: ##############
objc[1763]: AUTORELEASE POOLS for thread 0x10b379000
objc[1763]: 19 releases pending.
objc[1763]: [0x7fd8c4000000] ................ PAGE (hot) (cold)
objc[1763]: [0x7fd8c4000050] ################ POOL 0x7fd8c4000050
objc[1763]: [0x7fd8c40000c8] 0x7fd8c372e9f0 NSObject
objc[1763]: ##############
此种情况在iOS9.0以后已经得到优化不会有此操作。但是在低版本中会存在多次使用。随着iOS系统的不断升级,其系统的各种资源操作也在不断。这我们开发提供了方便。但是我们却不能懈怠,而只是简单的使用。一名合格的开发工程师不仅要做到会用还要知道为什么。
补充如何输出确认已被autorelease的对象状况:
//非ARC可以使用NSAutoreleasePool累的非公开方法 showPools。
[NSAutoreleasePool showPools];
//在ARC与运行时系统下使用非公开函数 _objc_autoreleasePoolPrint().
//函数声明
extern void _objc_autoreleasePoolPrint();
//autoreleasePool 调试输出开始
_objc_autoreleasePoolPrint();
文章内容总结于Objective-C高级编程,其实描述的部分问题已经被苹果优化与当前iOS系统不符,如有错误请与我联系 我会及时改正。