不使用 "init" 方法初始化实例变量?

Instance variable initialized without using "init" method?

我正处于 Objective-C 学习曲线的第一阶段,所以请耐心等待 :)。

我正在阅读 Apple 文档并在那里做练习。我遇到了特定对象初始化的问题,因为我在 Xcode.

中出现了意想不到的(在我看来)行为

进入正题(简单点):

第 1 步:

我已从名为 XYZPerson 的自定义 class 中声明了简单变量。它看起来像这样:

 XYZPerson *randomPerson;

"If" 检查返回的初始化对象 "Not Initialized"(如预期)。

if(randomPerson == nil) {
        NSLog(@"Random person is not initialized");
    } else {
        NSLog(@"Random person is  initialized");
    }

第 2 步:

我已经使用此变量上的 "alloc" 字为此对象分配了内存。据我了解,在这个阶段,这个变量的内存被分配。它也是returns指针?

代码行如下所示:

XYZPerson *randomPerson = [XYZPerson alloc];

检查 "nil" 让我感到惊讶:(它执行 "else" 语句)。

if(randomPerson == nil) {  
        NSLog(@"Random person is not initialized");
    } else {
        NSLog(@"Random person is  initialized");  
    }

我也可以向这个对象发送消息,它们执行得很好,无需调用 "init" 方法。

怎么会这样?我错过了什么吗?在这个实例上调用 "init" 方法之前,如何初始化 "randomPerson" 变量?为什么 "init" 会出现在第一位?

此外,此处接受的答案 Difference between ! and nil check on Objective-C object 表示在 alloc 方法中所有对象都设置为 nil!

我来自 Java,有一种使用 "new" 关键字声明对象的方法。如果不使用 "new",对象的实例将始终是 "null",并且对该实例调用方法将导致 "NULLPOINTEREXPECTION Error".

P.S是objectiveC中的"nil",与Java中的"NULL"一样吗?

整个项目如下所示:

主要方法:

 XYZPerson *randomPerson = [XYZPerson alloc];

    if(randomPerson == nil) {

        NSLog(@"Random person is not initialized");

    } else {
        NSLog(@"Random person is  initialized");
    }

**XYZ Person Class:**

    #import "XYZPerson.h"

@implementation XYZPerson

-(void)sayHello {

    //[self saySomething];

}

-(void)saySomething:(NSString *) greeting {

    NSLog(@"%@", greeting);

}



@end

我 post 在评论中链接的那个答案之外添加了一个答案,原因有二:

一个。你的Q略有不同。

乙。我没有详细确认链接的答案。

首先对您的附加问题:是的,nil 是 Objectice-C 的 NULL。但也有一些不同:

一个。在大多数情况下(使用 ARC)对指针(而不是对象本身)的引用是用 nil.

初始化的
XYZPerson *person; // Usually automatically set to nil.

乙。在 Objective-C 中允许向 nil 发送消息,不会抛出异常 returns NO00.0nil,或 null resp 的任何表示。零(如果它没有像整数那样的空表示)用于该类型。有时这是有意为之,您可以放心。

两个你的主要问题:

使用 +alloc 创建实例对象后,所有实例变量 (ivars) 都设置为 NO00.0nil 或无论 null 的表示形式如何。零是那种类型。您不应将此类 ivar 显式设置为该值。

例如,如果 class XYZPerson 的实例具有输入名称 NSString* 的 ivar,则 ivar 将为 nil。所以,有人可能会认为裸 -init 没有任何意义,因为它不接受参数,因此什么也不做。但是您根本不知道:也许 -init 中还做了其他事情。而且,对于 Java 开发人员来说,这可能是一个惊喜,-init returns 一个对象引用,因此您无法知道 -init 是否替换了实例对象,例如双色调.所以即使你看不出其中有任何意义,给实例对象的第一条消息也必须是 init。 (是的,在很多情况下你不会看到任何区别,但你不知道,是否有或将来会有。它是API合同的一部分,所以这样做。)

有一点不同意链接的答案:

发送 +new… 而不是 +alloc -init 是更好的方法。

一个。如果您使用简单的 +new,那么在许多情况下它发送 +alloc -init 是正确的。因此很明显,这并不比发送 +alloc -init 好或坏。它就是这样做的。您总是必须查看文档,是否允许使用 +new+alloc -init 进行裸初始化。但在这种情况下,您可能不想进行裸初始化,因为它毫无意义。

乙。有时 class 的实现者更容易收到 class 对象的 new 消息。