为什么alloc和init已在Objective-C分别叫什么?
-
21-09-2019 - |
题
请注意:我是比较新的Objective-C和从Java和PHP正在来临
。有人能向我解释为什么我总是要首先分配,然后初始化实例?
无法此被在init方法完成这样的:
+ (MyClass*)init {
MyClass *instance = [MyClass alloc];
[instance setFoo:@"bla"];
return instance;
}
+ (MyClass*)initWithString:(NSString*)text {
MyClass *instance = [MyClass init];
[instance setFoo:text];
return instance;
}
...
这是刚刚从旧的C天残遗,还是有东西,我没有看到?
我知道这是不是因为我可以和随时调用alloc和初始化的问题,但因为它是一个有点乏味,我想至少知道我为什么这样做。
我喜欢的语言的表现,到目前为止,但是这是我想以认为Objective-C的方式充分了解的东西。
谢谢!
解决方案
+新端部向上发送的alloc +消息发送到类和-init消息到任何来自+ ALLOC回来。
这接着从使用+新消息(这是一个Smalltalk的想法)的达石的会议离去的原因是,在早期,他们遇到的情况下,他们希望能够进行初始化同一对象多于一次。
其他提示
由于创建实例和初始化一个实例是两个单独的作业。
您发送alloc
消息给类来获得一个未初始化的实例。然后,您必须初始化实例,你往往有几种方法可以做到这一点。例如:
myStr = [[NSString alloc] init]; //Empty string
myStr = [[NSString alloc] initWithFormat:@"%@.%@", parentKeyPath, key];
myStr = [[NSString alloc] initWithData:utf16data encoding:NSUnicodeStringEncoding error:&error];
myStr = [[NSString alloc] initWithContentsOfURL:URL encoding:NSUTF8StringEncoding error:&error];
每个的这些初始化在一个完全不同的方式的字符串。你如何初始化字符串取决于您希望从初始化什么。
当然,没有人喜欢写alloc
然后init
然后autorelease
每一次,所以你通常有方便的方法(例如,stringWithFormat:
),其执行所有三个步骤你。
编辑:欲了解更多有关此主题,包括评论者必不可少的见解,请参阅我的博客文章“的统一”。
请参阅NSZone
。
+alloc
是快捷方式削减+allocWithZone:
,这是用于优化存储器分配的机制可可提供。
所以,你必须做这样的事情的选项:
foo = [[NSString allocWithZone:MyZone] initWithString:@"Foo"];
foo2 = [foo copyWithZone:MyZone];
后面存储器区的想法是,如果有大量的被频繁分配和释放类似的对象它可能更有效地使用单独的存储器区,用于这些对象。
为了功能分区是有效的,你会希望有可用的+allocWithZone:
每一个NSObject的子类,因此你需要单独的分配和初始化。您可以创建并使用所有你想要的快捷方式,就像+new
,但骨子里你需要初始化一个已经被分配对象的-init
方法。
“分离实例创建的配置和初始化阶段提供了许多好处。它可以使用+ ALLOC类方法的任何变化分配一个实例,然后使用任何可用的初始化新instance.This使它可以创建自己的初始化方法,而无需提供的所有分配方法可选的实施方式。 很少创建新的分配方法,因为现有的方法几乎可以满足各种需要。然而,一个或多个新的初始值设定项,几乎每一个类创建。由于分配和初始化阶段的分离,初始化的实现只需要应对新的实例变量,完全可以忽略的问题外加四舍五入allocation.The分离简化了编写初始化的过程。此外,可可标准初始化像-initWithCoder:与实例的工作,无论实例的方式存储的被分配。 分配和初始化分离的一个负面后果是需要注意公约,如指定initializer.You必须知道哪些方法是指定的初始化程序以及如何创建和子类文档新初始化的。从长远来看,使用指定的初始简化软件开发,但要作出theTwo级的创作模式增加了Cocoa开发早期学习曲线的参数。“的
(c)中可可设计模式由Erik M.巴克和Donald A.亚克曼
您不必。您可以使用[MyClass new]
。这类似于您的假想init
方法。
基本上,Objective-C的,它不具有垃圾收集最初,分离的存储器分配和初始化类的概念。这就是为什么有两种截然不同的方法。当你调用alloc
,你明确地分配内存。
大多数类有你所要求的。你以前为什么这是喜欢它,为什么你不会总是想用这一切的时候,但如果你读的文档类,你会看到许多类的方法是这样的行为,他们经常被用来得到答案。
有关的NSString你有,例如:
+ (id)string // (Empty string)
+ (id)stringWithFormat:... // Formatted string (like you use)
+ (id)stringWithContentsOfURL:... // String populated with contents of URL
等。你会再使用此类似:NSString *myString = [NSString stringWithFormat:@"Hello %@\n", userName];
大多数其它类具有此,像NSArray的:
+ (id)array
+ (id)arrayWithContentsOfFile:...
+ (id)arrayWithContentsOfURL:...
+ (id)arrayWithObjects:...
您只需要阅读文档。 :)和阅读你为什么不想使用太多此类对方回复。
<强>的alloc 强>:内存分配/给予对象的参考。现在参考具有记忆的财产,但没有做任何事情。该存储器是空的(最稀有的情况下)或与一些匿名数据。
<强> alloc和初始化强>:分配的内存被清洁/清空。存储器由零位启动。
<强> alloc和initwithdata ... 强>:分配的内存被启动与推崇的类的属性的期望数据
例如,当您购买的情节你占有。这个情节给你,因为它是毁了砖或老房子可能是在那里。这是的的alloc 即可。
当你清理你的阴谋,并删除所有的污垢和垃圾。这是的的alloc以init。强>
当你构建到一些有价值的房子就变得更有意义给你。并且它是的的alloc initwith ... 强>