学习Objective-C并阅读示例代码,我注意到对象通常是使用以下方法创建的:
SomeObject *myObject = [[SomeObject alloc] init];
代替:
SomeObject *myObject = [SomeObject new];
据我所知,这是有原因的吗?
学习Objective-C并阅读示例代码,我注意到对象通常是使用以下方法创建的:
SomeObject *myObject = [[SomeObject alloc] init];
代替:
SomeObject *myObject = [SomeObject new];
据我所知,这是有原因的吗?
Answers:
这里有很多原因:http : //macresearch.org/difference-between-alloc-init-and-new
一些选定的是:
new
不支持自定义初始化程序(如initWithString
)alloc-init
比 new
一般认为,您应该使用自己喜欢的任何东西。
+newWithString:
如果您已经实施了,也没有什么可以阻止您实施-initWithString
。虽然不常见。就个人而言,我总是new
在指定的初始值设定项init
为时使用,太短而甜蜜。
+newWithString:
。这打破了关注点分离。因为无论何时您只想使用-init
,都没有理由不使用+new
。
[[NSString alloc] initWithFormat:...]
和[NSString stringWithFormat:...]
都是等效的。您是说Apple违反了关注点分离,不应该以这种方式实施吗?(注意:我并不想屈服;我只是想获得更多信息,并且知道跟随苹果的领导有时是否是个坏主意。)
这个问题很老,但是我只是为了好玩而写了一些例子,也许您会发现它有用;)
#import "InitAllocNewTest.h"
@implementation InitAllocNewTest
+(id)alloc{
NSLog(@"Allocating...");
return [super alloc];
}
-(id)init{
NSLog(@"Initializing...");
return [super init];
}
@end
在主要功能中,这两个语句:
[[InitAllocNewTest alloc] init];
和
[InitAllocNewTest new];
结果相同:
2013-03-06 16:45:44.125 XMLTest[18370:207] Allocating... 2013-03-06 16:45:44.128 XMLTest[18370:207] Initializing...
[[InitAllocNewTest alloc] init]
在[InitAllocNewTest new]
不受影响的情况下不会编译。(对于没有换行符的道歉,等等)
+new
等同+alloc/-init
于Apple的NSObject
实现。这几乎不可能改变,但是根据您的偏执程度,Apple的文档+new
似乎允许将来更改实现(并打破对等原则)。出于这个原因,由于“显式胜于隐式”和历史连续性,Objective-C社区通常避免使用+new
。但是,您通常可以通过对Java的顽强使用来发现最近来Objective-C的Java使用者+new
。
+new
自NeXT时代以来一直存在。如果有什么+new
迹象表明某人很早以前就学习过objc,我看到很多人刚接触过这种语言,或者甚至已经写了多年的语言,但显然在iOS繁荣之后,他们并不知道这+new
意味着什么。第二,就像+new
已经很老的NeXT时代一样,Apple会以破坏旧代码的方式进行更改,这非常疯狂,特别是考虑到自己的代码库可能杂乱无章。
new
成语来自Smalltalk。它也用在Ruby中,Objective-C和Ruby都从Smalltalk派生了许多语法和约定。
如果new为您完成了工作,那么它也会使您的代码适度地变小。如果您另外打电话[[SomeClass alloc] init]
在代码中的许多不同位置进行,则将在new的实现中(即在objc运行时中)创建一个热点,这将减少缓存未命中的次数。
以我的理解,如果您需要使用自定义初始化程序,请使用[[SomeClass alloc] initCustom]
。
如果不这样做,请使用[SomeClass new]
。
init
函数,然后使用它即可。[[SomeClass alloc] init];
如果您需要参数,请不要执行任何操作[[SomeClass alloc] initWith:...];
。最后,如果您init
使用自定义实现覆盖了该函数,则可以new
在创建对象时调用,并且该对象仍会调用该自定义init
实现。