美文网首页iOS开发
OC 类属性探究

OC 类属性探究

作者: LGKODY | 来源:发表于2018-11-24 14:47 被阅读169次

    这个问题的起源于我们知道类方法是存在元类对象中,那么类属性是否也存在元类对象中?这个问题咋一看可能就会回答说:“存在的”。但是有个哥们就提出 OC 中有类属性吗?所以才有了这篇文章的探究。

    一、什么是类属性

    首先类属性是存在的。在 2016 的 WWDC 上指出,从 Xcode8开始,LLVM 已经支持 OC 显示的声明类属性,以便和 Swift 的类属性进行交互操作。其中 OC 中的类属性通过 class 关键字显示声明,如下图示:

    二、类属性是否存在元类对象中

    上面我们已经知道了什么是类属性,接着我们来看一下类属性是否存在元类对象中。可以通过如下代码打印一下元类对象中的属性列表。

    /** 1、获取元类对象 */
    Class metaClass = object_getClass([Person class]);
    /** 2、获取元类属性列表 */
    unsigned int count = 0;
    objc_property_t *propertList = class_copyPropertyList(metaClass, &count);
    for (int i = 0; i < count; i++) {
        NSLog(@"%s",property_getName(propertList[i]));
    }
    

    其中 Person 类中只声明了一个类属性

    @interface Person : NSObject
    
    @property (class) NSString *name;
    
    @end
    

    对应控制台打印结果如我们预想的一样打印出来了 name 属性,验证成功。

    三、类属性如何使用

    一开始在接触这个类属性时,很简单的认为可以直接通过点语法进行使用,结果 too young,too simple;直接就崩溃掉了,也就意味着类属性没有 set 方法。于是笔者又接着去打印了一下 Method List,空空如也。黑人问号脸?紧接着就在 WWDC 中找到了类属性的使用介绍,使用 class 声明的属性是不会自动合成 ivar 以及 set/get 方法,需要手动合成。隐隐感到类属性的鸡肋。

    四、使用动态方法解析来处理类属性

    上述介绍了可以手动合成 ivar 和 set/get 方法。接着我们来通过动态方法解析来进行处理。

    在Person.m文件中添加一下代码

    + (BOOL)resolveClassMethod:(SEL)sel{
        NSString *methodName = NSStringFromSelector(sel);
        if ([methodName isEqualToString:@"setName:"]) {
            return class_addMethod(object_getClass([Person class]), sel, (IMP)customSetName, "v@:@");
        }
        if ([methodName isEqualToString:@"name"]) {
            return class_addMethod(object_getClass([Person class]), sel, (IMP)customGetName, "@@:");
        }
        return NO;
    }
    
    void customSetName(id self, SEL _cmd, NSString *param){
        objc_setAssociatedObject(self, LGCLASSIVARKEY, param, OBJC_ASSOCIATION_COPY);
    }
    
    id customGetName(id self, SEL _cmd){
        return objc_getAssociatedObject(self, LGCLASSIVARKEY);
    }
    
    

    测试访问类属性

    Person.name = @"hello";
    NSLog(@"person name value --- %@",Person.name);
    

    经过上述处理如我们所愿能够正常访问 name 属性

    总结

    以上就是我们关于类属性的探究。现对本文知识点进行一下总结

    • OC 中类属性通过 class 关键字进行声明,且类属性存在元类对象中

    • 类属性不会自动合成 ivar 以及 set/get 方法,需要手动合成

    ps : 本文中部分图片引用来自 WWDC2016

    相关文章

      网友评论

        本文标题:OC 类属性探究

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