我最喜欢Cocoa的一个方面是可读性因素。
最令我烦恼的事情之一是方便施工人员强制重复的惯例。
以下是一个例子:
[NSString stringWithString:s]
[NSNumber numberWithDouble:d]
[NSValue valueWithInt:i]
[NSDictionary dictionaryWithObjectsAndKeys:<blah>]
等
为什么惯例不会简单地用“with”这个词启动方便构造函数?所以我们会:
[NSString withString:s]
[NSNumber withDouble:d]
[NSValue withInt:i]
[NSDictionary withObjectsAndKeys:<blah>]
等
这是一个小小的讨论点,但我认为我会抛弃那个,看看有没有比我更有影响力的人可以解释我头脑中的所有回声。
显然,我不打算请求AAPL重新编写appKit以支持我的建议,但有没有反对命名我自己的便利构造函数的论据?
当然,我可以在自己的代码中使用我想要的任何约定,但我讨厌盲目地向上游游泳。
答案 0 :(得分:13)
实际上有一个技术原因就是这样。如果每个shoelaceWithString:
类型的方法都改为withString:
,我们最终会得到一个可怕的大量具有相同命名方法和不同签名的类。这对编译器的静态类型检查起了很大的作用,并且可能导致它抛出各种恼人的和不必要的警告。
还有Cocoa文化的一个方面,开发人员喜欢他们的代码自我记录。这意味着方法名称表示它们的参数是什么以及它们返回的内容。 Apple的编码指南实际上警告了名称模糊的方法,建议在名称中添加单词以明确方法的作用更为可取。
答案 1 :(得分:10)
因为它是一致的。
有以下方法:
[NSDictionary dictionary]
[NSArray array]
摆脱with
之前的一切显然不是一个选择。保持这些,但缩短其他人会在方便方法的命名方面引入不一致。
便捷方法与init
和initWith…
方法一致。
答案 2 :(得分:3)
我认为这只是可可框架的一般“说出你的意思”一词哲学的一部分。一些选择:
[UIView setAnimationBeginsFromCurrentState]
[UITableView scrollToNearestSelectedRowAtScrollPosition]
[UIApplication didRegisterForRemoteNotificationsWithDeviceToken]
等
ETA:
为了回答有关构造函数的具体问题,我喜欢它们完成方式的一个方面是在x-code中很容易识别哪些方法是构造函数类型方法。例如,您开始输入:
[NSString string
并且“intellisense”将方法列表向下划分为以“string”开头的那些方法,当然这些方法都是构造方法(并且所有这些方法都很方便地组合在一起)。同样的事情适用于“init”约定。
答案 3 :(得分:3)
最终,我相信Cocoa框架(以及它之前的NextStep框架)所体现的Objective-C哲学是显式的,易于维护优先于代码的简洁性。这种哲学的主要证据是Objective-C选择器具有命名参数(例如-[NSObject performSelector:withObject:]
)。
对于+[NSString stringWithString:]
等工厂方法,必须记住子类可以覆盖这些类方法以返回子类(例如NSNumber
等类集群。
因此,您最终可能会调用[MyPoorlyNamedSubclass stringWithString:]
这样的调用,在这种情况下,-[MyPoorlyNamedSubclass withString:]
对返回的对象类型不会有明显的信息(请回想一下,许多工厂方法返回类型{{1} })。另一方面,id
表明该方法将返回一个字符串(或其子类)。
答案 4 :(得分:2)
他们还使用一个额外的单词来判断对象是否已自动释放。 initWithFormat用于非自动释放,当它的stringWithFormat被自动释放时...我猜他们只是用这种方式告诉读者该对象使用什么样的内存管理...
答案 5 :(得分:-2)
如果你不喜欢它,为什么不写出你在所有项目中包含的一堆#define语句?