我正在尝试以不同的方式从int main()
初始化XYZPerson
中的属性firstName
和lastName
。(我正在学习OC并探索初始化值的不同方法)
但是,对于firstName
,NSLog
总是返回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。我知道这很可能是一个非常愚蠢的错误,所以请不要对我太苛刻…谢谢!
是的,成功了!但我想知道为什么在设置之前将其存储为本地属性不起作用?
firstName
指向的地址不是保持不变吗?
确实如此,这就是为什么您的代码不起作用。。。
以下是一些优势,但希望能让概念得到理解。
让我们从属性后退一步,看看变量,您拥有的属性只是变量,周围有一些代码,对发生的事情没有影响。
变量只是一个名为的框,该框能够存储特定类型的东西的(计算机)表示,也称为value。例如声明:
int height;
是一条使用可用[1]框的指令,该框能够容纳类型为int
的事物的表示,并将该框命名为height
。
当你给一个变量赋值时,发生的事情是盒子里已经有的东西被扔掉[2],然后被赋值的值的副本被放在盒子里。
当您从变量中读取时,会生成一个框中内容的副本并返回给您。
现在,框中存储的值的类型无关紧要,上面对过程的描述仍然正确。
在您的情况下,存储在框中的是NSString *
类型的值,即引用或指针,指向表示(无论计算机以何种方式)字符串的东西,本质上,该引用就是字符串的表示。
现在考虑一下任务:
height = 42;
这总是将42
的表示分配到名为height
的变量/框中——整数文本总是表示相同的值[3]。
对于字符串文字也是如此,因此文字@"Jonny"
总是表示字符串";Jonny";。
现在,让我们看看您的代码,并描述它在(底层)变量方面所做的事情(属性只是包装器):
NSString *firstName = [somePerson firstName];
将somePerson
的firstName
变量中的当前值复制到局部变量firstName
中。根据您在代码somePerson
的firstName
中此时报告的内容,包含null
的表示形式,因此这就是复制的内容。
[somePerson setFirstName:@"Jonny"];
将@"Jonny"
的表示复制到somePerson
的firstName
变量中,丢弃已经存在的内容——在您的情况下是null
的表示
[somePerson setLastName:@"Appleseed"];
将@"Appleseed"
的表示复制到somePerson
的lastName
变量中
NSLog(@"%@ %@", firstName, [somePerson lastName]);
复制局部变量firstName
(null
的表示)和somePerson
的lastName
(@"Appleseed"
的表示)中的表示,并将它们传递给NSLog
以转换为可打印文本并输出。
你的误解可能源于听说了NSMutableString
型。其中之一由一个框表示,该框的内容可以被修改(又称"突变"),而不是简单地被替换。NSMutableString
的表示是指向其框的引用/指针,就像NSString
一样,但在这种情况下,框中的内容可以修改,而引用/指针将保持不变,因为框本身的名称不会更改。
希望帮助多于困惑!(使用图片/白板更容易解释。)
[1]计算机如何找到可用的盒子在这里很有趣,但并不重要。
[2] ";扔掉";可以非常投入,当你学习时,你会发现母马,有一种叫做";垃圾收集";你会在术语";ARC";在Objective-C中。但同样,这对你的问题并不重要。。。
[3] 那些对FORTRAN早期有足够了解的老年人希望大声说";啊,但是"这时站在角落里;-)