-, @zpasternac, " " . Objective-C . , CoreData .
, - , LazyClass, , lazyArray (. ). , , , +alloc -init, . NSMutableDictionary, myVars. , API , .
, , . .
LazyClass.h
@interface LazyClass : NSObject
@property NSMutableDictionary *myVars;
@property NSArray *lazyArray;
@end
LazyClass.m
#import "LazyClass.h"
#import <objc/objc-runtime.h>
@implementation LazyClass
@dynamic lazyArray;
- (instancetype)init {
self = [super init];
self.myVars = [NSMutableDictionary dictionary];
return self;
}
- (NSMutableDictionary *)getMyVars {
return self.myVars;
}
id dynamicGetterMethodIMP(id self, SEL _cmd) {
const char *selName = sel_getName(_cmd);
NSString *selNSName = [NSString stringWithCString:selName encoding:NSUTF8StringEncoding];
NSString *keyPath = [NSString stringWithFormat:@"myVars.%@", selNSName];
if (![self valueForKeyPath:keyPath]) {
objc_property_t property = class_getProperty([self class], selName);
const char *attr = property_getAttributes(property);
NSString *attrString = [[NSString alloc] initWithCString:attr encoding:NSUTF8StringEncoding];
NSString *typeAttr = [[attrString componentsSeparatedByString:@","] firstObject];
NSString *typeName = [typeAttr substringWithRange:NSMakeRange(3, typeAttr.length - 4)];
Class typeClass = NSClassFromString(typeName);
[self setValue:[[typeClass alloc] init] forKeyPath:keyPath];
}
return [self valueForKeyPath:keyPath];
}
void dynamicSetterMethodIMP(id self, SEL _cmd, id value) {
NSString *propertyName = NSStringFromSelector(_cmd);
propertyName = [propertyName stringByReplacingOccurrencesOfString:@"set" withString:@""];
propertyName = [propertyName stringByReplacingOccurrencesOfString:@":" withString:@""];
propertyName = [NSString stringWithFormat:@"%@%@", [propertyName substringToIndex:1].lowercaseString, [propertyName substringFromIndex:1]];
NSString *keyPath = [NSString stringWithFormat:@"myVars.%@", propertyName];
[self setValue:value forKeyPath:keyPath];
}
+ (BOOL)resolveInstanceMethod:(SEL)aSEL {
if ([NSStringFromSelector(aSEL) containsString:@"set"]) {
class_addMethod([self class], aSEL, (IMP)dynamicSetterMethodIMP, "^?");
} else {
class_addMethod([self class], aSEL, (IMP)dynamicGetterMethodIMP, "v@:");
}
return YES;
}
@end
Documentation