不是翻译
chapter 03 使用Objects(不翻译objects)
Objective-c 和 Gnustep提供了很多object分配和内存管理的条框(framework),objc(以下通指objective-c)为objects提供独立了的内存分配和初始化的步骤,gnustep为内存管理提供了三种方案。
3.1 初始化和分配objects
不象其他OO语言,objc为objects暴露内存管理和初始化两个步骤,每一个class(在objc中)都有一个+alloc
方法来创建未初始化实例(blank new instances)
,然而,初始化工作应该交给对象方法,而不是类方法,默认的初始化就是-init
id newObj = [[SomeClass alloc]init];
调用类方法alloc
时返回一个未初始化的实例,也就是
alloc将所有实例变量内存设为0,然后初始一个特殊的isa变量,这个变量指向object's class
,以此允许实例对消息机制做回应(respond).
实际上,两部合一也可以,但不推荐
:
id newObj = [SomeClass new];
- new = alloc + init 两步
- new可以被重写,例如实现像c++那种拷贝构造(在已有对象上复制一份)
3.1.1 有参初始化(c++有参构造函数)
id pt = [[Point alloc] initWithX:1.5 Y:2.0];
- 内存不足以分配时返回nil,参数传入错误时返回nil
- 如: NSString的 initWithContentsOfFile可能传入错误文件名以至于产生nil
3.1.2 内存分配区块(Zones)
- Gnustep对一片内存区域的叫法为Zone,这个Zone为一个类NSZone表示
+(id)alloc;
+(id)allocWithZone:(NSZone*)zone;
- 95%的情况是你不要考虑Zone,那是极致性能的事,一般人做不到
3.1.3 内存回收
- objects不用就回收
-(dealloc);
- 对于objects,不共享的内存应该回收,这部分不是很重点
3.2 内存管理
可供选用的内存管理方案:
- 显式管理:alloc dealloc
- 引用计数:retain release autorelease pools
- 垃圾回收机制
3.2.2 openstep style 引用计数 内存管理
Coin *c = [[Coin alloc] initWithValue:10];// count 1
[c retain];// retain count now 2
[c release];// retain count now 1
[c release];// when count 0, calls `dealloc`
NSString *msg = [[NSString alloc] initWithString: @"test"];// count 1
NSLog(msg);// count 2
[msg release];// count 1
- 在方法里引用计数更为复杂,
我也不清楚这里是否是正确描述
-(void)setVar:(Var *newVar)
{
[newVar retain];// newVar count 1
[foo release];// private variable
foo = newVar;
}
不甚推荐
,手动引用计数过于复杂
3.2.2.1 Autorelease Pools
-(NSString *)getStatus
{
NSString *status =
[[NSString alloc] initWithFormat:"Count is %d",[self getCount]];
[status autorelease];
// NSLog(status); error,不能再使用了
return status;
}
3.2.3 垃圾回收,宏
Macro Functionality
RETAIN(foo); [foo retain];
RELEASE(foo); [foo release];
AUTORELEASE(foo); [foo autorelease];
ASSIGN(foo, bar); [bar retain]; [foo release]; foo = bar;
ASSIGNCOPY(foo, bar); [foo release]; foo = [bar copy];
DESTROY(foo); [foo release]; foo = nil;
- 这部分看代码实例会比较合适
3.2.4 推荐方法
- 使用垃圾回收小节的宏来管理内存