美文网首页
runtime(3)--class

runtime(3)--class

作者: 初灬终 | 来源:发表于2018-11-26 19:29 被阅读3次

三.类

1.Dynamically Creating a Class

目标代码

@interface Product : NSObject 
@property (readonly) NSString *name; 
@property (readonly) double price;
- (instancetype)initWithName:(NSString *)name price:(double)price;
@end

@implementation Product
- (instancetype)initWithName:(NSString *)name
                       price:(double)price
{
    self = [super init];
    if(!self) {
        return nil; 
    }
    self.name = name; 
    self.price = price;
    return self;
 }
@end

runtime代码

Class c = objc_allocateClassPair([NSObject class], "Product", 0); 
class_addIvar(c, "name", sizeof(id), log2(sizeof(id)), @encode(id));
class_addIvar(c, "price", sizeof(double), sizeof(double), @encode(double));
Ivar nameIvar = class_getInstanceVariable(c, "name"); 
ptrdiff_t priceIvarOffset = ivar_getOffset(class_getInstanceVariable(c, "price"));

IMP initIMP = imp_implementationWithBlock( ^(id self, NSString *name, double price) {
    object_setIvar(self, nameIvar, name);
    char *ptr = ((char *)(__bridge void *)self) + priceIvarOffset; 
    //void *memcpy(void*dest, const void *src, size_t n);
    //由src指向地址为起始地址的连续n个字节的数据复制到以destin指向地址为起始地址的空间内。
    memcpy(ptr, &price, sizeof(price));
    return self; 
});
const char *initTypes = [[NSString stringWithFormat:@"%s%s%s%s%s%s", @encode(id),@encode(id), @encode(SEL), @encode(id), @encode(id), @encode(NSUInteger)] UTF8String];
class_addMethod(c, @selector(initWithFirstName:lastName:age:),initIMP, initTypes);
IMP nameIMP = imp_implementationWithBlock(^(id self) { 
    return object_getIvar(self, nameIvar);
});
const char *nameTypes = [[NSString stringWithFormat:@"%s%s%s",@encode(id), @encode(id), @encode(SEL)] UTF8String];

class_addMethod(c, @selector(name), nameIMP, nameTypes);
IMP priceIMP = imp_implementationWithBlock(^(id self) {
    char *ptr = ((char *)(__bridge void *)self) + priceIvarOffset; 
    double price;
    memcpy(&price, ptr, sizeof(price));
    return price; 
});
const char *priceTypes = [[NSString stringWithFormat:@"%s%s%s", @encode(double), @encode(id), @encode(SEL)] UTF8String];
class_addMethod(c, @selector(age), priceIMP, priceTypes); objc_registerClassPair(c);

执行

Product *widget = [[Product alloc] initWithName:@"Widget" price:50.00];
NSLog(@"%@: %g", widget.name, widget.price);

相关文章

网友评论

      本文标题:runtime(3)--class

      本文链接:https://www.haomeiwen.com/subject/taxgxqtx.html