0

我刚刚开始学习 Objective-C,我对输出感到困惑。试图通过实例方法中的属性来理解 self 的用法。为什么在 Objective-C 实例方法中使用 self 和不使用 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,然后我修改 name 可变字符串变量并再次调用 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 来修改 setName 实例方法并直接设置属性 Name 和 Email,我不会得到相同的输出。

-(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

谁能解释为什么?我的印象是我是否使用自我。或否,我正在访问相同的实例属性并分配值,因此输出不应更改。

4

1 回答 1

1

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

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

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

Name = [name copy];

因为这尊重您的属性定义所说的您将要执行的操作。

于 2013-11-03T19:17:52.720 回答