簡體   English   中英

Objective-C只讀副本屬性和IVR

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM