【发布时间】:2010-10-03 07:37:24
【问题描述】:
谁能向我解释一下 init 和 alloc 在 Obj-C 中的作用。我正在阅读这本 obj-c 书,它提供了一个创建对象的示例,但并没有真正详细介绍它的作用。 alloc 返回什么? init 返回什么?
Animal * k = [Animal alloc];
k = [k init];
【问题讨论】:
标签: objective-c
谁能向我解释一下 init 和 alloc 在 Obj-C 中的作用。我正在阅读这本 obj-c 书,它提供了一个创建对象的示例,但并没有真正详细介绍它的作用。 alloc 返回什么? init 返回什么?
Animal * k = [Animal alloc];
k = [k init];
【问题讨论】:
标签: objective-c
alloc 分配一块内存来保存对象,并返回指针。
MyClass* myObj = [MyClass alloc];
myObj 还不能使用,因为它的内部状态没有正确设置。所以,不要写这样的代码。
init 设置对象的初始条件并返回。请注意,[a init] 返回的内容可能与a 不同。这解释了 Yannick 编写的代码:
-init{
self=[super init]; // 1.
if(self){ // 2.
....
}
return self; // 3.
}
init,设置超类的实例变量等。这可能会返回不等于原始self 的内容,因此您需要将返回的内容分配给self。 self 不为nil,则表示超类控制的部分已正确初始化。现在您执行初始化。所有实例变量都设置为nil(如果它是对象)和0(如果它是整数)。您需要执行其他初始设置。 self。返回的self 可能与分配的不同!因此,您需要将init 的结果分配给您的变量。这建议了一个重要的教训:永远不要将呼叫拆分为 alloc 和 init。不要写:
MyClass* myObj = [MyClass alloc];
[myObj init];
因为[myObj init] 可能会返回其他内容。不要试图通过写作来解决这个问题:
MyClass* myObj = [MyClass alloc];
myObj=[myObj init];
因为你最终会忘记在第二行写 myObj= 部分。
总是写:
MyClass* myObj = [[MyClass alloc] init];
我也不推荐写:
MyClass* myObj = [MyClass new];
因为它没有正确调用初始化方法:有些类不接受普通的init。比如NSView需要initWithFrame:,不能用new调用。所以,也不要使用new。
【讨论】:
-init,您可以直接调用+new。如果您查看+(id)new 的实现,它实际上是return [[self alloc]init];
alloc init 与new 是非常好的做法。习惯性地使用alloc init 永远不会遇到错误,但习惯使用new 时可能会遇到错误。
最简单的形式:
alloc:分配的缩写,保留一个内存位置并返回指向该内存位置的指针。然后将该指针存储在 k 变量中。
init:初始化的缩写,设置对象并返回对象。 init 方法取决于对象,但通常涉及将 init 消息发送到超类。如果(超类的)该 init 方法返回一个对象(不是 nil),则可能会根据该类的任务设置一些 ivars。
--
一个初始化实现的例子,Schedule 类用一个空数组初始化它的通道 ivar。基本上,您给 Schedule 对象一个自我整理的机会,这样它就可以在创建后开始接收消息。您可以从 init 方法中删除频道初始化,但是您必须检查频道 ivar 在 Schedule 类的每个方法中是否为 nil,如果确实为 nil,则对其进行初始化。
- (Schedule*)init {
self = [super init];
if (self) {
channels = [[NSMutableArray alloc] initWithCapacity:0];
}
return self;
}
【讨论】:
alloc 和 init 是继承自 NSObject 的两个方法 您可以提供自己的方法或从 NSObject 调用方法
alloc 分配内存来创建你的类的一个新实例(@interface) init 初始化该实例的内容,默认情况下 init 将所有成员值设置为 0/nil 但是您可以创建自己的 init 方法来自定义所做的事情。
Animal * k = [[Animal alloc] init]; // creates a new Animal object
你也可以写
Animal * k = [Animal new]; // which would be a bit more similar to other languages
【讨论】:
NSObject 根类提供了一个类方法,alloc, alloc:保留一个内存位置并返回指向该内存位置的指针。
alloc 方法还有另一项重要任务,即通过将分配给对象属性的内存设置为零来清除它们。
这避免了内存包含之前存储的垃圾的常见问题,但是
不足以完全初始化一个对象。
您需要结合对 alloc 的调用和对 init 的调用,另一个 NSObject 方法:
(id)初始化; init 方法被一个类用来确保它的属性在创建时具有合适的初始值。 分配和初始化对象的正确方法是将 alloc 调用嵌套在对 init 的调用中,如下所示:
ClassName *objectName = [ClassName alloc] init];
来自:苹果文档
【讨论】:
Alloc 会为对象分配内存,但 Init 将对象放入内存并设置默认值。
【讨论】: