Objective c alloc和init它们实际上做什么

Objective c alloc和init它们实际上做什么,objective-c,Objective C,有人能给我解释一下init和alloc在Obj-C中的作用吗?我正在读这本Obj-C的书,书中给出了一个创建对象的例子,但它并没有详细介绍它的作用。alloc返回什么?init返回什么 Animal * k = [Animal alloc]; k = [k init]; 以最简单的形式: alloc:allocation的缩写,保留内存位置并返回指向该内存位置的指针。然后,该指针存储在k变量中 init:初始化的缩写,设置对象并返回对象。init方法依赖于对象,但它通常涉及将init消息发送

有人能给我解释一下init和alloc在Obj-C中的作用吗?我正在读这本Obj-C的书,书中给出了一个创建对象的例子,但它并没有详细介绍它的作用。alloc返回什么?init返回什么

Animal * k = [Animal alloc];
k = [k init];
以最简单的形式:

  • alloc:allocation的缩写,保留内存位置并返回指向该内存位置的指针。然后,该指针存储在k变量中

  • init:初始化的缩写,设置对象并返回对象。init方法依赖于对象,但它通常涉及将init消息发送到超类。如果(超类的)init方法返回一个对象(不是nil),那么根据该类的任务可能会设置一些ivar

--

作为初始化实现的示例,Schedule类使用空数组初始化其通道ivar。基本上,您可以给Schedule对象一个自行排序的机会,以便它可以在创建后开始接收消息。您可以从init方法中删除通道初始化,但随后必须检查Schedule类的每个方法中的通道ivar是否为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
  • alloc
    分配一块内存来保存对象,并返回指针

    MyClass* myObj = [MyClass alloc];
    
    myObj
    尚未使用,因为其内部状态未正确设置。所以,不要编写这样的代码

  • init
    设置对象的初始条件并返回它。请注意,
    [a init]
    返回的内容可能不同于解释Yannick编写的代码的
    a

    -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

Alloc将为对象分配内存,但Init将对象放入内存并设置默认值

NSObject根类提供了一个类方法,allocalloc:保留内存位置并返回指向该内存位置的指针

alloc方法还有另一项重要任务,即通过将对象属性设置为零来清除为对象属性分配的内存

这避免了通常的问题,即内存包含以前存储的任何内容的垃圾,但是

不足以完全初始化对象。

您需要将对alloc的调用与对init的调用结合起来,这是另一个NSObject方法:

  • (id)init; 类使用init方法来确保其属性在创建时具有合适的初始值。 分配和初始化对象的正确方法是将alloc调用嵌套在对init的调用中,如下所示:

    ClassName*objectName=[ClassName alloc]init]


from:apple documents

设置对象意味着什么?他们的回报是什么?我已经扩展了我的答案。很好的解释!感谢您这么说,如果您不需要自定义的
-init
,您可以直接调用
+new
。如果您查看
+(id)new
的实现,它实际上是
返回[[self-alloc]init]我有一个问题Yuji。变量myObj是指向内存位置的指针,对吗?您的观点是“首先,您需要调用超类的init,以设置超类的实例变量等,这些变量可能返回不等于原始自我的内容”,那么你的意思是在超类中再次分配一个新对象,因为指向内存位置的指针会因此而改变?通常init是一个初始化类成员的方法,为什么指针会改变是非常奇怪的@GilSand我知道的一个老问题,但对于新手来说:使用
alloc init
vs
new
确实是一个很好的实践。习惯性地使用
alloc init
,你永远不会遇到bug,但习惯性地使用
new
,你可能会遇到bug。请解释你的答案。