Objective-C 从另一个 Class Returns 设置 属性 Null
Objective-C Set Property from Another Class Returns Null
我正在尝试以不同的方式从我的 int main()
中初始化 XYZPerson
中的属性 firstName
和 lastName
。 (正在学习OC,正在探索不同的初始化值的方式)
但是,对于 firstName
,NSLog
总是 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 *
类型的值,即 reference 或 pointer表示(计算机以任何方式表示)字符串的东西,本质上是引用 是 字符串的表示形式。
现在考虑作业:
height = 42;
这总是将 42
的表示分配给名为 height
的 variable/box – 整数文字 始终表示相同的值 [3 ].
字符串文字也是如此,所以文字@"Jonny"
总是表示字符串“Jonny”。
现在让我们看看您的代码并根据(底层)变量(属性只是包装器)描述它在做什么:
NSString *firstName = [somePerson firstName];
将somePerson
的firstName
变量中的当前值复制到局部变量firstName
中。根据您此时在代码中报告的内容 somePerson
的 firstName
包含 null
的表示形式,因此这就是复制的内容。
[somePerson setFirstName:@"Jonny"];
将 @"Jonny"
的表示复制到 somePerson
的 firstName
变量中,丢弃已经存在的任何内容——在您的例子中是 null
[=46= 的表示]
[somePerson setLastName:@"Appleseed"];
将 @"Appleseed"
的表示复制到 somePerson
的 lastName
变量中
NSLog(@"%@ %@", firstName, [somePerson lastName]);
复制局部变量 firstName
中的表示 - null
的表示 - 以及 somePerson
的 lastName
中的表示 - @"Appleseed"
的表示– 并将它们传递给 NSLog
以转换为可打印的文本并输出。
您的误解可能源于听说类型NSMutableString
。其中之一由一个框表示,其内容可以 modified(也称为“突变”),而不是简单地 replaced。 NSMutableString
的表示是其框的 reference/pointer,就像 NSString
一样,但在这种情况下,框内的内容可以修改,而 reference/pointer 将保留和盒子本身的名字一样,不会变。
希望对您有所帮助而不是困惑! (使用pictures/a白板更容易解释。)
[1] 计算机如何找到可用的盒子很有趣,但在这里并不重要。
[2]“扔掉”可能会涉及很多,您会在学习的过程中发现母马,有一种叫做“垃圾收集”的东西,您会在 Objective-C。但这对你的问题并不重要......
[3] 那些 old/learned 足以了解早期 FORTRAN 的人,他们希望在此时站起来说“啊,但是......” ;-)
我正在尝试以不同的方式从我的 int main()
中初始化 XYZPerson
中的属性 firstName
和 lastName
。 (正在学习OC,正在探索不同的初始化值的方式)
但是,对于 firstName
,NSLog
总是 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 *
类型的值,即 reference 或 pointer表示(计算机以任何方式表示)字符串的东西,本质上是引用 是 字符串的表示形式。
现在考虑作业:
height = 42;
这总是将 42
的表示分配给名为 height
的 variable/box – 整数文字 始终表示相同的值 [3 ].
字符串文字也是如此,所以文字@"Jonny"
总是表示字符串“Jonny”。
现在让我们看看您的代码并根据(底层)变量(属性只是包装器)描述它在做什么:
NSString *firstName = [somePerson firstName];
将somePerson
的firstName
变量中的当前值复制到局部变量firstName
中。根据您此时在代码中报告的内容 somePerson
的 firstName
包含 null
的表示形式,因此这就是复制的内容。
[somePerson setFirstName:@"Jonny"];
将 @"Jonny"
的表示复制到 somePerson
的 firstName
变量中,丢弃已经存在的任何内容——在您的例子中是 null
[=46= 的表示]
[somePerson setLastName:@"Appleseed"];
将 @"Appleseed"
的表示复制到 somePerson
的 lastName
变量中
NSLog(@"%@ %@", firstName, [somePerson lastName]);
复制局部变量 firstName
中的表示 - null
的表示 - 以及 somePerson
的 lastName
中的表示 - @"Appleseed"
的表示– 并将它们传递给 NSLog
以转换为可打印的文本并输出。
您的误解可能源于听说类型NSMutableString
。其中之一由一个框表示,其内容可以 modified(也称为“突变”),而不是简单地 replaced。 NSMutableString
的表示是其框的 reference/pointer,就像 NSString
一样,但在这种情况下,框内的内容可以修改,而 reference/pointer 将保留和盒子本身的名字一样,不会变。
希望对您有所帮助而不是困惑! (使用pictures/a白板更容易解释。)
[1] 计算机如何找到可用的盒子很有趣,但在这里并不重要。
[2]“扔掉”可能会涉及很多,您会在学习的过程中发现母马,有一种叫做“垃圾收集”的东西,您会在 Objective-C。但这对你的问题并不重要......
[3] 那些 old/learned 足以了解早期 FORTRAN 的人,他们希望在此时站起来说“啊,但是......” ;-)