Objective-c readonly copy properties and ivars -
i'm try grok properties declared both copy , readonly in objective-c, , specifically, whether have copy myself. in init methods. evidence suggests do:
@interface : nsobject @property(nonatomic, copy, readonly) nsdata *test; - (instancetype)initwithdata:(nsdata *)data; @end @implementation - (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 alloc] initwithdata:d1]; nslog(@"%lx", (unsigned long)d1); nslog(@"%lx", (unsigned long)a.test); return 0; }
i had thought self.test = data
in init method, not permitted because it's readonly (not unexpectedly). of course, self.test = [data copy]
ensures 2 different objects.
so: there way create readonly property in objective-c copies incoming value, or sufficiently edge case combination pointless , have copying myself manually anyway?
a @property
declaration merely shorthand accessor/mutator method declarations, , (in cases) synthesized implementations said accessor/mutator methods.
in case, @property(nonatomic, copy, readonly) nsdata *test
declaration expands equivalent code:
@interface : nsobject { nsdata* _test; } - (nsdata*)test; @end @implementation - (nsdata*)test { return _test; } @end
there no settest:
mutator method because property declared readonly
, copy
attribute has no effect.
you can implement own mutator method:
- (void)settest:(nsdata*)newvalue { _test = [newvalue copy]; }
or, can have compiler synthesize mutator method declaring read/write property in private class extension in implementation file:
// a.m: @interface a() @property (nonatomic, copy) nsdata* test; @end
both cases allow use test
mutator method copy value _test
instance variable:
- (instancetype)initwithdata:(nsdata *)data { if ((self = [super init]) != nil) { self.test = data; } return self; }
the end result is:
@interface : nsobject @property(nonatomic, copy, readonly) nsdata* test; - (instancetype)initwithdata:(nsdata*)data; @end @interface a() @property (nonatomic, copy) nsdata* test; @end @implementation - (instancetype)initwithdata:(nsdata*)data { if ((self = [super init]) != nil) { self.test = data; } return self; } @end
Comments
Post a Comment