为什么在Objective-C实例方法中使用self和without self设置属性会显示不同的结果?

时间:2013-11-03 18:52:25

标签: objective-c string

我刚开始学习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

任何人都可以解释原因吗?我的印象是我是否使用自我。或者,我访问相同的实例属性并分配值,因此输出不应更改。

1 个答案:

答案 0 :(得分:1)

  

我的印象是我是否使用自己。或者,我正在访问相同的实例属性并分配值

相同的实例变量,是的,但不是以相同的方式。通过使用self.name,您正在调用setter方法,该方法正在实现您在属性上指定的copy。相反,通过直接设置实例变量,您不会复制,因此当更改可变字符串时,它会随处更改。

因此,在这种情况下使用self.的替代方法是:

Name = [name copy];

因为这会尊重您的属性定义所说的内容。