学习Objective-C并阅读示例代码,我注意到对象通常是使用以下方法创建的:
SomeObject *myObject = [[SomeObject alloc] init];
代替:
SomeObject *myObject = [SomeObject new];
是否有理由这样做,因为我已经读到它们是等同的?
1> Jeremy Stanl..:
这里有很多原因:http://macresearch.org/difference-between-alloc-init-and-new
一些选定的是:
new
不支持自定义初始值设定项(如initWithString
)
alloc-init
比...更明确 new
一般意见似乎是你应该使用你喜欢的任何东西.
如果你已经实现了`-initWithString`,那么没有什么可以阻止你实现`+ newWithString:`.虽然不常见.就个人而言,当指定的初始化程序是`init`时,我总是使用`new`,只是太短而且很甜.
我知道这是一个旧线程,但我只想强调你_should not_实现`+ newWithString:`.这打破了关注点的分离.因为当你只想使用`-init`时,没有理由不使用`+ new`.
如果您的类使用-init作为指定的初始值设定项,+ new将调用它.Jeremy所指的是你有一个不是-init的自定义初始化程序.-initWithName :,例如.
@JonathanSterling:Apple有很多例子,他们似乎正在做你建议的事情; 例如`[[NSString alloc] initWithFormat:...]`和`[NSString stringWithFormat:...]`都是等价的.你是说苹果违反了关注点,不应该以这种方式实施吗?(注意:我不是试图居高临下;我只想获得更多信息,并且知道跟苹果公司的领导有时是个坏主意.)
在我看来,自定义初始化器是一个令人信服的理由,支持[[alloc] init]].谢谢你的快速回答.
@Senseful我相信可以追溯到ARC(或垃圾收集)之前的日子.这两件事我们不相同.stringWithFormat:将返回一个自动释放的字符串,而alloc:init:需要手动释放或自动释放,否则会导致内存泄漏.
new()因此是一种方便的方法,因为没有涉及alloc和init吗?因此它不像alloc-> init那样返回一个自动释放的对象吗?
好的,现在是2015年,让我们停止让新手(和我)混淆__wrong__信息.使用`new`是不是很糟糕?我个人认为它没有任何问题,也没有看到`+ newWithString:`.
答案中提供的链接似乎对我不起作用,所以我不知道这是否已经解决,但是:确实调用alloc和init方法的新方法不仅仅是向管道添加另一个堆栈推送,因此使代码运行得更慢(即使差异可以忽略不计)?或编译器是否解决了这个问题?
2> guitar_freak..:
很老的问题,但我写了一些只是为了好玩的例子 - 也许你会发现它很有用;)
#import "InitAllocNewTest.h"
@implementation InitAllocNewTest
+(id)alloc{
NSLog(@"Allocating...");
return [super alloc];
}
-(id)init{
NSLog(@"Initializing...");
return [super init];
}
@end
在main函数中都有两个语句:
[[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.h"如下:@interface InitAllocNewTest:NSObject - (instancetype)__ unavailable init; @end` [[InitAllocNewTest alloc] init]`将不会编译,而`[InitAllocNewTest new]`不受影响.(对于缺少换行符等道歉)
很好的答案!只是想补充一点,使用+ new非常适用于你只需要使用-init并且没有更专业的情况,例如-initWithSomething:...
3> Barry Wark..:
+new
相当于+alloc/-init
Apple的NSObject
实现.这种情况不太可能发生变化,但根据您的偏执程度,Apple的文档+new
似乎允许在未来改变实施(并打破等效性).出于这个原因,因为"显式优于隐式"而且对于历史连续性,Objective-C社区通常会避免+new
.但是,您可以通过他们的顽固使用来发现最近的Java角色到Objective-C +new
.
我赞成这一点,因为自从NeXT时代以来,"+ new"已经存在.如果有什么东西"+ new"是某个人很久以前学过objc的迹象; 我看到很多人对这种语言感到新鲜,或者甚至已经写了多年,但显然在iOS热潮之后,他们不知道"+ new"的意思.其次,由于"+ new"非常古老,而且从NeXT时代开始,Apple会以破坏旧代码的方式改变它,特别是考虑到他们自己的代码库可能会被它弄乱.
虽然这通常是正确的,但也有一个支持简洁的阵营,在这种情况下,只有在有明确和现在的关注保证时才更明确.
我无法想象为什么一个你必须输入MORE的解决方案将是首选的(alloc init),特别是在像Objective-C这样的冗长语言中,保存击键可以节省你的时间.那些"顽固的Java开发人员"只是利用他们的分析技能花更少的时间编写代码,而不是不必要地键入产生相同功能结果的额外字符.
它只允许更改alloc.明确表示-init的文档将被调用.所以它更依赖于你是否覆盖了alloc.
4> Brian Campbe..:
通常,您需要传递参数init
,因此您将使用不同的方法,例如[[SomeObject alloc] initWithString: @"Foo"]
.如果你习惯于写这篇文章,你会习惯这样做,所以[[SomeObject alloc] init]
可能更自然地来[SomeObject new]
.
5> user739711..:
一个简短的回答是:
两者都是一样的.但
'new'仅适用于基本的'init'初始值设定项,不适用于其他初始值设定项(例如initWithString :).