我刚开始学习Objective-C而且我对输出感到困惑。试图在实例方法中理解self与属性的用法。为什么在Objective-C实例方法中使用self和without self设置属性会显示不同的结果?
我使用copy属性声明了属性,并假设对属性的赋值将是副本而不是直接引用。
#import <Foundation/Foundation.h>
@interface AddressCard : NSObject
//using a copy attribute
@property (copy, nonatomic) NSString *Name, *Email;
-(void) setName:(NSString *) name andEmail: (NSString *) email;
-(void) print;
@end
在实现setName实例方法中,我使用self.Name和self.Email来设置属性值
@implementation AddressCard
@synthesize Name;
@synthesize Email;
-(void) setName:(NSString *) name andEmail:(NSString *)email
{
self.Name = name;
self.Email = email;
}
-(void) print
{
NSLog(@"Name : %@ , Email: %@", Name, Email);
}
@end
在主程序中,我将NSMutableString传递给setName实例方法,然后调用print然后修改名称mutable string变量并再次调用print。
#import <Foundation/Foundation.h>
#import "AddressCard.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
AddressCard *card = [[AddressCard alloc] init];
//declaring local mutable string variables to use them for passing as parameters
//to setName instance method
NSMutableString *name = [NSMutableString stringWithString: @"John Doe"];
NSMutableString *email = [NSMutableString stringWithString: @"john.doe@email.com"];
//passing the name and email mutables as parameters
[card setName: name andEmail: email];
[card print];
//Modifying name variable which previously passed as parameter to setName method
[name appendString: @" MODIFIED"];
NSLog(@"Output Should Not Change");
//Print again
[card print];
}
return 0;
}
修改主程序中可变字符串变量的名称不会影响第二行结果。
姓名:John Doe,电子邮件:john.doe@email.com
输出不应改变
姓名:John Doe,电子邮件:john.doe@email.com
但是如果我通过删除self并直接设置属性Name和Email来修改setName实例方法,我就得不到相同的输出。
-(void) setName:(NSString *) name andEmail:(NSString *)email
{
// self.Name = name
Name = name;
// self.Email = email;
Email = email;
}
主程序中对可变名称变量的修改反映在输出中。
姓名:John Doe,电子邮件:john.doe@email.com
输出不应改变
姓名: John Doe MODIFIED ,电子邮件:john.doe@email.com
任何人都可以解释原因吗?我的印象是我是否使用自我。或者,我访问相同的实例属性并分配值,因此输出不应更改。
答案 0 :(得分:1)
我的印象是我是否使用自己。或者,我正在访问相同的实例属性并分配值
相同的实例变量,是的,但不是以相同的方式。通过使用self.name
,您正在调用setter方法,该方法正在实现您在属性上指定的copy
。相反,通过直接设置实例变量,您不会复制,因此当更改可变字符串时,它会随处更改。
因此,在这种情况下使用self.
的替代方法是:
Name = [name copy];
因为这会尊重您的属性定义所说的内容。