[英]Objective-c readonly copy properties and ivars
我試圖查看在objective-c中聲明為copy和readonly的屬性,特別是是否必須自己復制。 在我的初始化方法中。 證據表明我願意:
@interface A : NSObject
@property(nonatomic, copy, readonly) NSData *test;
- (instancetype)initWithData:(NSData *)data;
@end
@implementation A
- (instancetype)initWithData:(NSData *)data {
if ((self = [super init]) != nil) {
_test = data;
}
return self;
}
@end
int main (void) {
NSData *d1 = [NSMutableData dataWithBytes:"1234" length:5];
A *a = [[A alloc] initWithData:d1];
NSLog(@"%lx", (unsigned long)d1);
NSLog(@"%lx", (unsigned long)a.test);
return 0;
}
我以為可以在自己的init方法中進行self.test = data
,但這是不允許的,因為它是只讀的(並非意外)。 當然, self.test = [data copy]
確保兩個不同的對象。
因此:有沒有一種方法可以在Objective-C中創建一個只讀屬性來復制傳入的值,或者是否足以使組合毫無意義,而且我還是必須手動復制自己?
@property
聲明只是某些訪問器/更改器方法聲明的簡寫,並且(在某些情況下)是所述訪問器/更改器方法的綜合實現。
在您的情況下, @property(nonatomic, copy, readonly) NSData *test
聲明擴展為以下等效代碼:
@interface A : NSObject
{
NSData* _test;
}
- (NSData*)test;
@end
@implementation A
- (NSData*)test
{
return _test;
}
@end
沒有setTest:
mutator方法,因為該屬性被聲明為readonly
,所以copy
屬性無效。
您可以實現自己的mutator方法:
- (void)setTest:(NSData*)newValue
{
_test = [newValue copy];
}
或者,可以通過在實現文件的私有類擴展中聲明讀/寫屬性,使編譯器為您合成mutator方法:
// A.m:
@interface A()
@property (nonatomic, copy) NSData* test;
@end
兩種情況都允許您使用test
mutator方法將值復制到_test
實例變量:
- (instancetype)initWithData:(NSData *)data {
if ((self = [super init]) != nil) {
self.test = data;
}
return self;
}
最終結果是:
@interface A : NSObject
@property(nonatomic, copy, readonly) NSData* test;
- (instancetype)initWithData:(NSData*)data;
@end
@interface A()
@property (nonatomic, copy) NSData* test;
@end
@implementation A
- (instancetype)initWithData:(NSData*)data {
if ((self = [super init]) != nil) {
self.test = data;
}
return self;
}
@end
除了Darren所說的之外, copy
屬性還描述了屬性設置程序具有的語義。 在初始值設定項中,您沒有使用setter,而是直接分配給實例變量。
也許有點難以理解,但是實例變量和屬性並不相同。 在這種情況下,它用於實現屬性。 但是,分配給實例變量與設置屬性不同。
如果您希望初始化程序也具有復制傳入數據的語義,則這是一個單獨的設計決策(盡管與屬性的語義一起使用是一個好主意)。 您可以按照Darren的建議使用私有設置器來實現,但是您也可以這樣做:
_test = [data copy];
在初始化程序中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.