iOS开发你需要知道的iOS 收藏篇ios

iOS Category---为什么只能加方法不能加属性

2020-08-21  本文已影响0人  枫紫_6174

一.面试题

            相信大家在面试的时候经常会被问到Category的实现原理,以及Category为什么只能加方法不能加属性?个人理解这个问题本身问的就有问题,首先我们看分类的底层代码

                        struct category_t {

                                    const char *name;

                                    classref_t cls;

                                    struct method_list_t *instanceMethods; // 对象方法

                                    struct method_list_t *classMethods; // 类方法

                                    struct protocol_list_t *protocols; // 协议

                                    struct property_list_t *instanceProperties; // 属性

                                    // Fields below this point are not always present on disk.

                                    struct property_list_t *_classProperties;

                                    method_list_t*methodsForMeta(boolisMeta) {

                                if(isMeta)returnclassMethods;

                                            elsereturninstanceMethods;

                            }

                        property_list_t*propertiesForMeta(boolisMeta,structheader_info *hi);

                    };

        通过上面的分类底层代码我们可以找到category_t 结构体,它里面包含了对象方法,类方法,协议,属性,既然分类的底层代码里面已经包含了属性,为什么我们面试的时候会被问到分类为什么不能添加属性?下面我们来揭开它的神秘面纱

        1.首先我们创建一个person类,再给penson类创建一个分类Person+TCText,在分类的.h文件


分类写上属性

这么写工程是不会报任何错误,给我们一种表面上其实是可以添加属性的,写上一个属性,系统会自动帮我们生成setter和getter方法,在分类里面写属性或者成员变量,系统只会帮我们做的一件事情就是它只会声明我们的setter和getter方法,不会帮我们实现,上面的这个属性等同于我们在分类里面写


无论上面何种写法,我们在ViewController都能访问TCName这个属性

但是,当我们在分类里面重写settet或者getter的时候,它就会出现:

为什么什么会报错了?因为分类的属性,系统不会自动帮我们生成_TCName(相关属性赋值可以看苹果官网API,这里不做解释),在这里我们如果写:


表面看上去不会报错,但是当外部访问TCName的时候,就会发现:

程序一旦运行起来,就会因为递归,程序闪退。

总结:不是说分类不能添加属性,是因为分类可以添加属性,但是由于系统不会自动帮分类的属性实现getter和setter方法,也不会帮其生成_TCName,无论你重写settet或者getter还是,你不能通过self.TCName去访问属性,重写了setter,这么访问就会发生递归,直接导致程序闪退。所以下次你该知道怎么回答面试官的问题了吧!!!

上一篇下一篇

猜你喜欢

热点阅读