我只是好奇这是对的还是不好的做法? (即使用类方法来分配/初始化实例)?我是否正确地认为我必须在main()中释放实例作为我唯一可以访问实例指针的地方?
// IMPLEMENTATION
+(id) newData {
DataPoint *myNewData;
myNewData = [[DataPoint alloc] init];
return myNewData;
}
// MAIN
DataPoint *myData;
myData = [DataPoint newData];
... stuff
[myData release];
也应该
myNewData = [[DataPoint alloc] init];
是(或无关紧要)
myNewData = [[self alloc] init];
奇怪的是,当我添加autorelease时,我得到了......
+(id) dataPoint {
return [[[self alloc] init] autorelease];
}
而不是(你将在主要版本中发布)
+(id) new {
return [[self alloc] init];
}
欢呼加里
答案 0 :(得分:14)
根据命名约定,您应该将其命名为+dataPoint
。分析器向你发射的原因是(按照惯例),使用“new”的类方法应返回具有+1保留计数的对象。你正在返回一个带有+0(自动释放)保留计数的对象,因此违反惯例。
正如在@ Peter的回答中提到的,要创建一个空对象,通常使用[ClassName className]
方法完成。例如:[NSArray array]
,[NSData data]
,[NSString string]
等。因此,您要做的就是将其重命名为[DataPoint dataPoint]
,然后将其实施为return [[[self alloc] init] autorelease];
最好使用[self alloc]
,因为它可以转换为子类。 IE,如果你创建一个MutableDataPoint子类,那么(如果你使用[self alloc]
)执行[MutableDataPoint dataPoint]
会返回MutableDataPoint
,而如果你把它留给[DataPoint alloc]
,它会回来作为DataPoint
对象(因为这就是你要分配的东西)。 (在旁注中,self
指的是在方法的上下文中操作的对象。例如方法,它是实例。对于类方法,它是Class
对象本身)
编辑:
如果您确实希望类方法返回具有+1保留计数的对象,那么(按照惯例),您只需要将其称为+new
(即DataPoint * p = [DataPoint new];
)。但是,+new
方法的使用似乎已经或多或少地被废弃,+alloc/-init...
或类便利方法是有利的选择。
编辑#2(Re:Edit_003):
我个人更喜欢前者(+dataPoint
),但仅仅因为+new
不常见,我不必记住-release
对象。但是,任何一个都是完全可以接受和正确的。
答案 1 :(得分:5)
你可以写得很整齐;
+ (id)dataPoint {
return [[[MyDataPoint alloc] init] autorelease];
}
注意:您仍应编写init方法;这种类方法通常用于方便。此外,如果您没有GC,则应根据内存管理规则自动释放返回值。
编辑重命名为+ dataPoint,由Dave更正。
答案 2 :(得分:2)
您的静态方法newData
是一个非常好的做法,您可以在整个Cocoa API中看到类似的方法(例如,[NSString string]和[NSData data])。
你应该做的唯一事情(如果你没有使用垃圾收集器)是将它添加到自动释放池。惯例是,如果从alloc,new,copy或mutableCopy获取新对象,则需要自己保留/释放它。如果您通过任何其他方式获得对象(您的newData
方法将符合“其他方式”),那么假设该对象已添加到自动释放池中,并且无需管理记住你自己。
至于[DataPoint alloc]
与[self alloc]
,他们都编译,并且从我所知道的内容同样有效。我自己来自Java背景,我建议[DataPoint alloc]
,因为你处于静态上下文(self
类似于java this
,不应该真的存在于非 - 静态背景)。当然,我对Objective-C很新,而且Objective-C不是Java,所以你的milage可能会有所不同。
答案 3 :(得分:1)
EDIT_002:
奇怪的是,当我添加autorelease时,我得到了......
一点也不奇怪。阅读它的内容:
Method返回一个具有+1保留计数(拥有引用)的Objective-C对象
您将方法命名为newData
。 new
方法返回拥有的引用。
对象已发送-autorelease消息
烨。就在那里。
对象作为拥有引用返回给调用者(传递给调用者的单个保留计数)
new
方法(例如newData
)会返回拥有引用,这意味着该new
方法的调用方会收到拥有引用。调用者应该拥有此对象。代替...
对象以+0(非拥有)保留计数
返回给调用者
您自动释放了该对象,否定了所有权。即使你应该这样做,你也不再返回拥有的引用。这总结在最后一面旗帜中:
具有+0保留计数的对象[sic]返回给调用者,其中预期+1(拥有)保留计数
调用者应该期望拥有该对象,因为它来自new
方法,但它没有,因为你自动释放它。因为调用者认为它拥有该对象,所以它应该稍后释放或自动释放它,但是因为你已经这样做了,所以这将是一个过度释放。
解决方案是遵守Cocoa命名约定并纠正这种期望违规。这意味着两种解决方案之一:
new
方法,并自动释放该对象。我会做#2,因为它更常见,通常对呼叫者的工作也少一些。