简体   繁体   English

类方法的对象分配?

[英]Object allocation from class method?

I am just curious if this is right, or bad practice? 我只是好奇这是对的,还是不好的做法? (ie using a class method to alloc/init an instance)? (即使用类方法来分配/初始化实例)? Also am I right in thinking that I have to release the instance in main() as its the only place I have access to the instance pointer? 我是否正确地认为我必须在main()中释放实例作为我唯一可以访问实例指针的地方?

// IMPLEMENTATION
+(id) newData {
    DataPoint *myNewData;
    myNewData = [[DataPoint alloc] init];
    return myNewData;
}

.

// MAIN
DataPoint *myData;
myData = [DataPoint newData];
... stuff
[myData release];

EDIT: 编辑:

Also should 也应该

myNewData = [[DataPoint alloc] init];

be (or does it not matter) 是(或无所谓)

myNewData = [[self alloc] init];

EDIT_002: EDIT_002:

Strange, when I add the autorelease I get ... 奇怪的是,当我添加autorelease时,我得到...

替代文字

EDIT_003: EDIT_003:

@Dave DeLong, one final question, what your saying is its perferable to: @Dave DeLong,最后一个问题,你的说法是什么:

+(id) dataPoint {
    return [[[self alloc] init] autorelease];
}

rather than (where you would release in main) 而不是(你将在主要发布的地方)

+(id) new {
    return [[self alloc] init];
}

cheers gary 欢呼加里

According to naming conventions, you should call it +dataPoint . 根据命名约定,您应该将其命名为+dataPoint The reason the analyzer is barfing at you is because (by convention), a class method that uses "new" is expected to return an object with a +1 retain count. 分析器向你发射的原因是(按照惯例),使用“new”的类方法应返回具有+1保留计数的对象。 You're returning an object with a +0 (autoreleased) retain count, and are therefore breaking convention. 您将返回一个具有+0(自动释放)保留计数的对象,因此违反了约定。

As was alluded to in @Peter's answer, to create an empty object, it's usually done with [ClassName className] methods. 正如在@ Peter的回答中提到的,要创建一个空对象,它通常使用[ClassName className]方法完成。 Ex: [NSArray array] , [NSData data] , [NSString string] , etc. So the proper thing for you to do would be to rename it [DataPoint dataPoint] and then implement it as return [[[self alloc] init] autorelease]; 例如: [NSArray array][NSData data][NSString string]等。所以你要做的就是将它重命名为[DataPoint dataPoint] ,然后将其实现为return [[[self alloc] init] autorelease];

Using [self alloc] is preferable, since it translates down to subclasses. 最好使用[self alloc] ,因为它可以转换为子类。 IE, if you create a MutableDataPoint subclass, then (if you use [self alloc] ) doing [MutableDataPoint dataPoint] returns a MutableDataPoint , whereas if you leave it as [DataPoint alloc] , it would come back as a DataPoint object (because that's what you're allocating). IE,如果你创建一个MutableDataPoint子类,那么(如果你使用[self alloc] )做[MutableDataPoint dataPoint]返回一个MutableDataPoint ,而如果你把它MutableDataPoint [DataPoint alloc] ,它会作为一个DataPoint对象回来(因为那是你分配的是什么)。 (On a side note, self refers to the object being operated on in the context of the method. For instance methods, it's the instance. For class methods, it's the Class object itself) (在旁注中, self指的是在方法的上下文中操作的对象。例如方法,它是实例。对于类方法,它是Class对象本身)

Edit: 编辑:

If you do want the class method to return an object with a +1 retain count, then (by convention), you'd just need to call it +new (ie, DataPoint * p = [DataPoint new]; ). 如果你确实希望类方法返回一个具有+1保留计数的对象,那么(按照惯例),你只需要调用它+new (即, DataPoint * p = [DataPoint new]; )。 However, use of the +new method seems to have fallen into more-or-less disuse, with +alloc/-init... or a class convenience method being the favorable alternatives. 然而, +new方法的使用似乎已经或多或少地被废弃, +alloc/-init...或类便利方法是有利的选择。

Edit #2 (Re: Edit_003): 编辑#2(Re:Edit_003):

I personally prefer the former ( +dataPoint ), but only because +new isn't as common and I don't have to remember to -release the object. 我个人更喜欢前者( +dataPoint ),但仅仅因为+new并不常见,我不必记得 - -release对象。 Either one is perfectly acceptable and correct, though. 但是,任何一个都是完全可以接受和正确的。

You can write it a lot neater as; 你可以写得很整齐;

+ (id)dataPoint {
    return [[[MyDataPoint alloc] init] autorelease];
}

Note: you should still write an init method; 注意:您仍应编写init方法; such class methods are usually used for convenience. 这种类方法通常用于方便。 Also, if you don't have GC, the return value should be autoreleased in line with the Memory Management rules. 此外,如果您没有GC,则应根据内存管理规则自动释放返回值。

Edit renamed to +dataPoint as corrected by Dave. 编辑重命名为+ dataPoint,由Dave更正。

Your static method newData is a perfectly ok practice, and you can see similar methods throughout the Cocoa API (just for example, [NSString string] and [NSData data] ). 你的静态方法newData是一个非常好的做法,你可以在整个Cocoa API中看到类似的方法(例如, [NSString string][NSData data] )。

The only thing you should be doing (if you're not using the garbage collector) is adding it to an autorelease pool. 你应该做的唯一事情(如果你没有使用垃圾收集器)是将它添加到自动释放池。 The convention is that if you get a new object from alloc, new, copy, or mutableCopy, you need to retain/release it yourself. 惯例是,如果从alloc,new,copy或mutableCopy获取新对象,则需要自己保留/释放它。 If you get an object through any other means (which your newData method would qualify as an "other means") then the assumption is that the object has been added to an autorelease pool, and there is no need to manage the memory yourself. 如果通过任何其他方式( newData方法将其作为“其他方法”)获得对象,则假设该对象已添加到自动释放池中,并且不需要自己管理内存。

As for the the [DataPoint alloc] vs. [self alloc] they both compile and both work equally well from what I can tell. 至于[DataPoint alloc][self alloc]它们都可以编译,并且从我能说的方面都可以同样有效。 Coming from a Java background myself, I'd suggest the [DataPoint alloc] since you're in a static context ( self being similar to the java this , shouldn't really existing in a non-static context). 从Java背景的我自己,我会建议[DataPoint alloc]因为你是在静态情况下( self是类似于Java this ,真的不应该在非静态上下文中存在的)。 Granted, I'm rather new to Objective-C, and Objective-C isn't Java by any stretch, so your milage may vary. 当然,我对Objective-C很新,而且Objective-C不是Java,所以你的milage可能会有所不同。

EDIT_002: EDIT_002:

Strange, when I add the autorelease I get ... 奇怪的是,当我添加autorelease时,我得到...

Not strange at all. 一点都不奇怪。 Read what it says: 阅读它的内容:

  1. Method returns an Objective-C object with a +1 retain count (owning reference) 方法返回一个具有+1保留计数的Objective-C对象(拥有引用)

    You named your method newData . 您将方法命名为newData A new method returns an owning reference. new方法返回拥有的引用。

  2. Object sent -autorelease message 对象发送-autorelease消息

    Yup. 对。 Right there. 在那里。

  3. Object returned to caller as owning reference (single retain count transferred to caller) 对象作为拥有引用返回给调用者(传递给调用者的单个保留计数)

    A new method (such as newData ) returns an owning reference, which means the caller of that new method receives an owning reference. new方法(例如newData )返回拥有引用,这意味着该new方法的调用者接收拥有引用。 The caller should own this object. 调用者应该拥有此对象。 Instead… 代替…

  4. Object returned to caller with a +0 (non-owning) retain count 对象以+0(非拥有)保留计数返回给调用者

    You autoreleased the object, negating the ownership. 你自动释放了对象,否定了所有权。 You're no longer returning an owning reference, even though you're supposed to. 即使你应该这样做,你也不再返回拥有的引用。 This is summed up in the last flag: 这总结在最后一面旗帜中:

  5. Object with +0 retain counts [sic] returned to caller where a +1 (owning) retain count is expected 具有+0保留计数的对象[sic]返回给调用者,其中预期+1(拥有)保留计数

    The caller should expect to own the object, since it came from a new method, but it doesn't, because you autoreleased it. 调用者应该期望拥有该对象,因为它来自一个new方法,但它没有,因为你自动释放它。 Because the caller thinks it owns the object, it should release or autorelease it later, but because you already did, this will be an over-release. 因为调用者认为它拥有该对象,所以它应该稍后释放或自动释放它,但是因为你已经这样做了,所以这将是一个过度释放。

The solution is to obey the Cocoa naming conventions and rectify this expectation-violation. 解决方案是遵守Cocoa命名约定并纠正这种期望违规。 This means one of two solutions: 这意味着两种解决方案之一:

  1. Keep the name as it is, and don't autorelease the object. 保持名称不变,不要自动释放对象。
  2. Change the name of the method so that it isn't a new method, and autorelease the object. 更改方法的名称,使其不是new方法,并自动释放该对象。

I'd do #2, as it's more usual and generally less work for callers. 我会做#2,因为它更常见,通常对呼叫者来说工作量更少。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM