Objective C - 创建和初始化对象的首选方法
这两种创建和初始化对象的方法中的哪一种更可取?
MyClass oClass = [[MyClass alloc] init];
oClass.length = 5;
oClass.text = @"Hello";
或者使用包含大约相同代码但看起来像这样的类方法:
MyClass oClass = [MyClass myClassWithLength:(int) 5 andText:(NSString *) @"Hello"];
当我看到事情以多种方式完成并且我不知道一种方式是否比另一种更好,或者为什么!时,我讨厌它!
Is one of these two ways to create and initialize an object preferable?
MyClass oClass = [[MyClass alloc] init];
oClass.length = 5;
oClass.text = @"Hello";
or using a class method that contains about the same code but looks like this:
MyClass oClass = [MyClass myClassWithLength:(int) 5 andText:(NSString *) @"Hello"];
I hate it when I see things done more than one way and I have no idea if one is better than the other, or why!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不要成为一个仇恨者。 :-)
顺便说一句,我假设您的意思是:(
编辑:删除了不必要的强制转换)
使用多个 init... 方法的原因是为了让开发人员更方便地创建正确初始化的实例。因此,举例来说,如果您发现开发人员经常需要创建具有长度和文本的 MyClass 实例,您可以通过提供允许他们一步完成此操作的 API 来让他们的工作变得更轻松。如果您发现开发人员还经常需要仅使用文本字符串创建 MyClass 实例,您还可以提供
-initWithText:
方法。如果以这种方式创建的实例经常用作临时对象(即不存储在实例变量或静态变量中),您还可以添加一个类便利方法,例如
+myClassWithText:
,它返回一个自动释放的实例使用提供的文本字符串初始化的 MyClass。至于哪一个更好:尽可能完全初始化对象总是更好,因此如果对象需要正确初始化两个值,请使用允许您提供两个参数的方法。如果您不需要存储对正在创建的实例的引用,请使用类便利方法,这样您的代码就不必处理内存管理。
Don't be a hater. :-)
By the way, I'm assuming you meant:
(Edit: removed unnecessary casts)
The reason for multiple init... methods is to make it more convenient for developers to create properly initialized instances. So, for example, if you find that developers often need to create instances of MyClass with a length and text, you make their life easier by providing an API that allows them to do that in one step. And if you find that developers also frequently need to create instances of MyClass with just a text string, you might also provide an
-initWithText:
method.And if the instances created this way are frequently used as temporary objects (i.e., not stored in instance variables or static variables), you might also add a class convenience method like
+myClassWithText:
that returns an autoreleased instance of MyClass initialized with the provided text string.As to which one is better: it's always better to fully initialize an object when possible, so if the object needs both values to be properly initialized, use the method that allows you to provide both arguments. And if you don't need to store a reference to the instance you're creating, use the class convenience method so your code doesn't have to deal with memory management.
如果对象在没有长度和文本的情况下无法使用,那么第二个选项可能更好。如果这些字段是可选的,那么第一个更好。
然而,我认为这个问题没有绝对的真理。
If the object is unusable without the length and text, then the second option might be better. If those fields are optional, then the first one is better.
However, I don't think there is absolute truth to this question.
如果您有一个具有许多属性的类,则不太可能在一行代码中将它们全部初始化。两种方法都适合我。
If you have a class with many properties it's very unlikely to initialize them all in one single line of code. Both ways work fine for me.
如果
initWithSomething:
方法可用,并且您想为这些属性提供初始值,我总是更喜欢它,因为它更简单。即使对于类的不可变版本,它也始终有效。但这两种 init 方法本质上都不是“更好”。类通常有一个或两个指定的初始值设定项,而所有其他类仅调用具有默认值的初始值设定项 - 它不一定使实例的属性保持不变。类的文档应指示其初始化程序的作用以及该类的指定初始化程序。例如,
[[NSDate alloc] init]
使用 NSDate 的指定初始化器initWithTimeIntervalSinceReferenceDate:
来创建表示当前日期和时间的日期对象。顺便说一句,这也意味着当你对一个类进行子类化时,你只需要重写它指定的初始值设定项。因为其他人只是这样称呼,所以他们免费获得你的新行为。
If an
initWithSomething:
method is available and you want to provide initial values for those properties, I would always prefer it just because it's simpler. It also will always work even with immutable versions of a class.But neither init method is inherently "better." Classes usually have one or two designated initializers and all the others just call those with default values — it doesn't necessarily leave the instance's properties untouched. The documentation for a class should indicate what its initializers do and which is the designated initializer for the class. For example,
[[NSDate alloc] init]
uses NSDate's designated initializer,initWithTimeIntervalSinceReferenceDate:
, to create a date object representing the current date and time.Incidentally, this also means that when you're subclassing a class, you only need to override its designated initializer. Since the others just call that, they get your new behavior for free.