Objective-C 从另一个 Class Returns 设置 属性 Null

Objective-C Set Property from Another Class Returns Null

我正在尝试以不同的方式从我的 int main() 中初始化 XYZPerson 中的属性 firstNamelastName。 (正在学习OC,正在探索不同的初始化值的方式)

但是,对于 firstNameNSLog 总是 returns null。我知道有很多问题和我的相似,但几乎所有的问题都倾向于一个特定的问题而不是语言语法本身。

#import <Foundation/Foundation.h>
#import "XYZShoutingPerson.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        XYZPerson *somePerson = [[XYZPerson alloc] init];
        
        NSString *firstName = [somePerson firstName];
        [somePerson setFirstName:@"Jonny"];
        [somePerson setLastName:@"Appleseed"];

        NSLog(@"%@ %@", firstName, [somePerson lastName]); // prints ```(null) Appleseed```
    }
    return 0;
}
@interface XYZPerson : NSObject

@property NSString *firstName;
@property NSString *lastName;

- (id)init;
- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName;
- (void)saySomething:(NSString *)greeting;

@end

我才刚刚开始学习Objective-C。我知道这很可能是一个非常愚蠢的错误,所以请不要对我太苛刻...谢谢!

Yeah, that worked! But I wonder why storing it as local property before setting it doesn't work? Doesn't the address firstName points to remains the same?

确实如此,这就是为什么您的代码不起作用...

以下内容绕过一些边缘,但希望能够理解这些概念。

让我们从属性退后一步,看看变量,您拥有的属性只是变量,周围有一些代码,这对这里发生的事情没有影响.

一个变量只是一个命名的 box,那个盒子能够存储(计算机)表示,也就是 value,具有特定 类型 的东西。例如声明:

int height;

是一条使用可用[1]框的指令,该框能够保存类型为 int 的事物的表示,并将该框命名为 height

当你给一个变量赋值时,盒子里已经存在的东西会被扔掉[2],然后被赋值的副本被放在盒子里.

当您从一个变量中读取时,会制作一个 副本 框中的内容并返回给您。

现在盒子里存的是什么类型的值都无所谓了,上面的过程描述依然成立。

在您的情况下,您的框中存储的是 NSString * 类型的值,即 referencepointer表示(计算机以任何方式表示)字符串的东西,本质上是引用 字符串的表示形式。

现在考虑作业:

height = 42;

这总是将 42 的表示分配给名为 height 的 variable/box – 整数文字 始终表示相同的值 [3 ].

字符串文字也是如此,所以文字@"Jonny"总是表示字符串“Jonny”。

现在让我们看看您的代码并根据(底层)变量(属性只是包装器)描述它在做什么:

NSString *firstName = [somePerson firstName];

somePersonfirstName变量中的当前值复制到局部变量firstName中。根据您此时在代码中报告的内容 somePersonfirstName 包含 null 的表示形式,因此这就是复制的内容。

[somePerson setFirstName:@"Jonny"];

@"Jonny" 的表示复制到 somePersonfirstName 变量中,丢弃已经存在的任何内容——在您的例子中是 null[=46= 的表示]

[somePerson setLastName:@"Appleseed"];

@"Appleseed" 的表示复制到 somePersonlastName 变量中

NSLog(@"%@ %@", firstName, [somePerson lastName]);

复制局部变量 firstName 中的表示 - null 的表示 - 以及 somePersonlastName 中的表示 - @"Appleseed" 的表示– 并将它们传递给 NSLog 以转换为可打印的文本并输出。

您的误解可能源于听说类型NSMutableString。其中之一由一个框表示,其内容可以 modified(也称为“突变”),而不是简单地 replacedNSMutableString 的表示是其框的 reference/pointer,就像 NSString 一样,但在这种情况下,框内的内容可以修改,而 reference/pointer 将保留和盒子本身的名字一样,不会变。

希望对您有所帮助而不是困惑! (使用pictures/a白板更容易解释。)


[1] 计算机如何找到可用的盒子很有趣,但在这里并不重要。

[2]“扔掉”可能会涉及很多,您会在学习的过程中发现母马,有一种叫做“垃圾收集”的东西,您会在 Objective-C。但这对你的问题并不重要......

[3] 那些 old/learned 足以了解早期 FORTRAN 的人,他们希望在此时站起来说“啊,但是......” ;-)