好的,这就是。
作为一名Java开发人员,我仍然在为ObjectiveC中的内存管理而苦苦挣扎。我已经掌握了所有基础知识,但有一段时间我遇到了挑战。
我想要做的是在Java中看起来像这样的东西:
MyObject myObject = new MyObject(new MyParameterObject());
MyObject
类的构造函数采用了MyParameterObject
类型的参数,我是即时启动的。
在ObjectiveC中,我尝试使用以下代码执行此操作:
MyObject *myObject = [[MyObject alloc] init:[[MyParameterObject alloc] init]];
但是,运行Build and Analyze工具会给我一个MyParameter
对象的“潜在泄漏”警告,当我使用Instruments测试它时确实会发生这种情况。我确实理解为什么会发生这种情况,因为我使用alloc
方法获取对象的所有权并且不放弃它,我只是不知道正确的方法。
我尝试使用
MyObject *myObject = [[MyObject alloc] init:[[[MyParameterObject alloc] init] autorelease]];
然后分析工具告诉我“对象发送 - 自动发送太多次了”。
我可以通过将init
MyParameterObject
方法修改为return [self autorelease];
来代替return self;
来解决问题。分析仍然警告潜在的泄漏,但实际上并没有发生。但是我认为这种方法违反了在ObjectiveC中管理内存的惯例,我真的希望以正确的方式做到这一点。
提前完成。
答案 0 :(得分:3)
好的,这是一个建议。
MyParameter *param = [[MyParam alloc] init];
MyObject *obj = [[MyObject alloc] initWithParam:param]; // do you know if param is retain'd or not?
[param release];
为什么这样?这是ObjC / Cocoa中使用的模式。您可以通过以下方式向NSArrays添加对象:
MyThing *thing = [[MyThing alloc] init];
[myMutableArray addObject: thing]; // this calls [thing retain]
[thing release];
您可能还想尝试这样做:
MyObject *obj = [[MyObject alloc] initWithParam: [MyParameter parameter]];
其中:
+ (id) parameter
{
return [[[self alloc] init] autorelease];
}
这样你就不用担心了。这与
相同[NSData data];
[NSArray array];
我希望有所帮助。通常,在另一个方法调用(如setter或其他init)中使用init
不是一个好主意。将它隐藏在类方法(+ (id) parameter
)后面意味着用户知道它将是autorelease
'd。
如果您不清楚retain
或release
的内容有多少,您可以随时执行以下操作:
[编辑]
警告:显然你是should never use-retainCount
。我发现教会学习者retain
'内存管理的基础知识很有用,但重点很明显。
Never Use it in actual code or for performance testing.这仅用于了解retain
的作用(我认为在这种情况下它的功能正常)。它永远不会为autorelease
或retain
或NSArray
或其他基础/ AppKit / UIKit类的对象提供智能答案
MyParameter *param = [[MyParam alloc] init];
NSLog(@"param retain count: %d",[param retainCount]); // should be 1
MyObject *obj = [[MyObject alloc] initWithParam:param];
NSLog(@"param retain count: %d",[param retainCount]); // should be 2, if MyObject retains it.
[param release];
NSLog(@"param retain count: %d",[param retainCount]); // should be 1
此外,当您dealloc
MyObject时,如果您在初始化过程中release
,则需要retain
参数。
Apple推出的以下guide应该可以帮助您更好地理解Objective-C内存管理。
答案 1 :(得分:2)
MyThing *thing = [[MyThing alloc] init];
[otherThing methodWithAThing:thing];
[thing release];
或:
[otherThing methodWithAThing:[[[MyThing alloc] init] autorelease]];
或(如果您正在使用的课程中有“便利构造函数”):
[otherThing methodWithAThing:[MyThing thing]];
答案 2 :(得分:0)
MyObject *myObject = [[MyObject alloc] init:[[[MyParameterObject alloc] init] autorelease]];
应该没问题,如果init中没有发布(在init中肯定没有发布)。我经常创建一个类方法,它创建一个自动释放的对象。所以代码是:
// using it:
MyObject *myObject = [[MyObject alloc] init:[MyParameterObject defaultParameters];
// in the class implementation of MyParameterObject
+ (MyParameterObject*) defaultParameters{
MyParameterObject* out = [[MyParameterObject alloc] init];
// set some values
return [out autorelease];
}
答案 3 :(得分:0)
[[MyObject alloc] init:[[[MyParameterObject alloc] init] autorelease]]
在不知道init方法发生了什么的情况下,这似乎很好。
但是,请注意,拼写这个“initWithParameterObject:”更加客观。尽管Obj-C的描述性方法名称实际上对代码可读性非常有用,但是他们禁止人们使用该语言。