2016-01-11 30 views
1

這是預期的行爲嗎?使用指定的inits時屬性的Objective-C複製屬性不起作用

例如,對於申報像這樣的類:

@interface XYZPerson : NSObject 

@property (nonatomic, copy) NSString *firstName; 
@property (nonatomic, copy) NSString *lastName; 

+ (instancetype)personWithFirstName:(NSString *)firstName lastName:(NSString *)lastName birthday:(NSDate *)birthday; 

@end 

@implementation XYZPerson 
+ (instancetype)personWithFirstName:(NSString *)firstName lastName:(NSString *)lastName birthday:(NSDate *)birthday { 
    return [[self alloc] initWithFirstName:firstName lastName:lastName birthday:birthday]; 
} 

- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName birthday:(NSDate *)birthday { 
    self = [super init]; 
    if (self) { 
     _firstName = firstName; 
     _lastName = lastName; 
     _birthday = birthday; 
    } 
    return self; 
} 

- (instancetype)init { 
    return [self initWithFirstName:@"John" lastName:@"Doe" birthday:[NSDate date]]; 
} 

,吸氣不會在以下複製:

NSMutableString *name1 = [NSMutableString stringWithString:@"First"]; 
NSDate *birthday1 = [NSDate dateWithYear:1900 month:10 day:10]; 

XYZPerson *person = [XYZPerson personWithFirstName:name1 lastName:@"Last" birthday:birthday1]; 

NSMutableString *n1 = (NSMutableString *)person.firstName; 
[n1 appendString:@"ttt"]; 

NSLog(@"%@", person.firstName); // Prints Firstttt 

然而,這將引發異常(這是預期的行爲,因爲下面的代碼在不可變的NSString上調用appendString

XYZPerson *person = [XYZPerson new]; 
person.firstName = name1; 
person.lastName = @"Last"; 
person.birthday = birthday1; 

NSMutableString *n1 = (NSMutableString *)person.firstName; 
[n1 appendString:@"ttt"]; 

NSLog(@"%@", person.firstName); 

我在代碼中丟失了什麼嗎?

更新 此外,如果這是預期的行爲,而不是一個異常,難道我們不應該使用性質工廠方法應該被複制?

+0

什麼是例外? –

+0

'原因:' - [NSTaggedPointerString appendString:]'這是預期的行爲 – BridgeTheGap

回答

2

您正在分配給支持變量。這不使用訪問器方法,也不會發生複製。

並將NSString *分配給NSMutableString *不會使其變爲可變。如果編譯器不給你一個警告,那麼在Xcode中改變你的設置。

+0

我故意檢查它的行爲。 (拋出異常是預期的行爲)此外,官方文檔建議用戶直接在初始化程序中設置伊娃。這種行爲令人困惑。 – BridgeTheGap

1

顯然我錯過閱讀以下部分:

如果您需要直接在初始化方法設置副本屬性的實例變量,例如,不要忘記設置的 原副本對象: