Objective-C runtime stores a list of declared properties as metadata with the class object. Metadata includes name, type, and property attributes. The runtime library also provides several functions for extracting this information. This means that the declared property is larger than a pair of accessor methods (getter / setter). My first question is: Why do we (or the runtime) need metadata?
As you know, a declared property cannot be redefined in subclasses (except for readwrite vs. readonly). But I have a script that guarantees:
@interface MyClass : MySuperClass <NSCopying, NSMutableCopying>
@property (nonatomic, copy, readonly) NSString *string;
- (id)initWithString:(NSString *)aString;
@end
@interface MyMutableClass : MyClass
@property (nonatomic, strong, readwrite) NSMutableString *string;
- (id)initWithString:(NSString *)aString;
@end
Of course, the compiler does not skip the above code. My solution is to substitute the declared property with a pair of access methods (read-only only):
@interface MyClass : MySuperClass <NSCopying, NSMutableCopying> {
NSString *_string;
}
- (id)initWithString:(NSString *)aString;
- (NSString *)string;
@end
@implementation MyClass
- (id)initWithString:(NSString *)aString {
self = [super init...];
if (self) {
_string = [aString copy];
}
return self;
}
- (NSString *)string {
return _string;
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
- (id)mutableCopyWithZone:(NSZone *)zone {
return [[MyMutableClass alloc] initWithString:self.string];
}
@end
@interface MyMutableClass : MyClass
- (id)initWithString:(NSString *)aString;
- (NSMutableString *)string;
- (void)setString:(NSMutableString *)aMutableString;
- (void)didMutateString;
@end
@implementation MyMutableClass
- (id)initWithString:(NSString *)aString {
self = [super init...];
if (self) {
_string = [aString mutableCopy];
}
return self;
}
- (NSMutableString *)string {
return (NSMutableString *)_string;
}
- (void)setString:(NSMutableString *)aMutableString {
_string = aMutableString;
}
- (void)didMutateString {
}
- (id)copyWithZone:(NSZone *)zone {
return [[MyClass alloc] initWithString:self.string];
}
@end
string , . , . , , . . . : ? ?
:
@interface MyClass : MySuperClass <NSCopying, NSMutableCopying> {
NSString *_string;
}
@property (nonatomic, copy, readonly) NSString *string;
- (id)initWithString:(NSString *)aString;
@end
@interface MyMutableClass: MyClass
- (id)initWithString:(NSString *)aString;
- (NSMutableString *)string;
- (void)setString:(NSMutableString *)aMutableString;
- (void)didMutateString;
@end
, , myMutableObject.string, , . [myMutableObject string]. , , , , . : getter/setter , ?