为什么要使用类方法构造函数而不是alloc/init?

6
有两种Objective C/Cocoa的构造函数选择:
1. 类构造函数
Product *product = [Product productWithIdentifier:@"Chocolate"];
// Use product

2. 分配 / 初始化 构造函数

Product *product = [[Product alloc] initWithIdentifier:@"Chocolate"];
// Use product
[product release];

我的工作

  • 我倾向于使用类方法,因为它看起来更干净,而且不需要释放。
  • 我看到很多alloc/init - 这样做有什么优势呢?

我的问题

  • 哪一个更可取?还是只是个人口味的问题?

代码

为了上下文,Product类将具有以下内容:

+(Product *)productWithIdentifier:(NSString *)identifier_ {
   return [[[[self class] alloc] initWithIdentifier:identifier] autorelease];
}

-(Product *)initWithIndentifier:(NSString *)identifier_ {
   self = [super init]
   if (self) {
       identifier = identifier_;
   }
   return self;
}
2个回答

5
在我看来,这两种方法最大的不同在于使用“类构造器”可以获得一个自动释放的对象;这是最方便的选择,当你需要:
  1. 将已分配的对象分配给 retain 属性时;
  2. 创建“临时”对象时(想想各种从另一个字符串构建字符串的 NSString 方法:在许多情况下,您需要“链接”这些调用;构造函数允许您“忘记”内存管理);
  3. 将对象添加到一些保留它的对象中(例如: addSubview
在这些情况下,“类构造器”的语法优势是首要的,但我认为,在内存管理方面,“类构造器”也使您的代码更加“安全”。
另一方面,当你创建一个对象以将其分配给一个 assign 属性(或者直接分配给一个没有属性的 ivar),那么 alloc/init 将完美地完成工作,并且比 “构造器” 更可取(在我看来)。
因此,最终取决于您将如何使用您分配的对象。类构造器是一种方便的方法。

5
如果您正在使用ARC,那么两种方法之间的差别不是很大。如果您没有使用ARC,则差异非常重要。
`alloc/init`组合会给您一个拥有的引用。这意味着您必须稍后进行`release`操作。`classnameWithFoo`变量返回一个非拥有的引用。您不能进行`release`操作。
这遵循通常的Cocoa命名约定。所有方法都返回非拥有(自动释放)实例,除了以`alloc`、`copy`、`mutableCopy`和`new`开头的方法。这些方法返回拥有的引用,您必须进行`release`操作。
使用哪种方法主要取决于口味。但是,如果您需要可以快速处理的临时对象,则`alloc`变体会导致稍微少一些方法调用(自动释放)。并且在循环中,它还可以减少最大内存占用。然而,在大多数情况下,这种成本降低是可以忽略不计的。

这两个答案非常接近,但是这个稍微好一点,因为它提到了内存占用问题。但另一个答案提到了“串联”调用。我希望我可以选择两个! - John Gallagher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接