zoukankan      html  css  js  c++  java
  • 第26条:勿在分类中声明属性

    属性是封装数据的方式(参见第6条)。

    属性只是定义实例变量及相关存取方法所用的“语法糖”,所以也应遵循同实例变量一样的规则。

    分类机制,应该将其理解为一种手段,目标在于扩展类的功能,而非封装数据。

    尽管从技术上说,分类里也可以声明属性,但这种做法应该尽量避免。

    原因是:除了“class-continuation分类”(参见第27条)之外,其他分类都无法向类中新增实例变量,因此,它们无法把实现属性所需的实例变量合成出来。

    所以开发者需要在分类中为该属性实现存取方法。

    1)此时可以把方法声明为@dynamic,也就是说,这些方法等到运行期再提供,编译器目前是看不见的。如果决定使用消息转发机制(参见第12条)在运行期拦截方法调用,并提供其实现,那么或许可以采用这种做法。

     

    2)关联对象(参见第10条)能够解决在分类中不能合成实例变量的问题。

    缺点:相似的代码要写很多遍,而且内存管理问题上容易出错。

    例:

    #import <objc/runtime.h>

    static const char *kFriendsPropertyKey = "kFriendsPropertyKey";

    @implementation Person(Friendship)

    -(NSArray*)friends {

      return objc_getAssociatedObject(self, kFriendsPropertyKey);

    }

    -(void)setFriends:(NSArray*)friends {

      objc_setAssociaedObject(self, kFriendsPropertyKey, friends, OBJC_ASSOCIATION_NONATOMIC);

    }

    @end

    3、只读属性可以在分类中使用。属性可以不需要由实例变量来实现。

    由于只读属性在.m中只有一个getter方法,

    即实现了该属性所需的全部方法,所以编译器不会再为属性自动合成实例变量。也就满足上面的条件了,编译器也就不会发出警告信息。

    总结:

    即便这3种方法可以实现,但不推荐。

    而应该把封装数据所用的全部属性都定义在主接口里。

    在“class-continuation分类”之外的其他分类中,可以定义存取方法,但尽量不要定义属性。

  • 相关阅读:
    excel生成数据地图
    利用web of science做论文综述
    机器学习算法一览图
    什么是机器学习?
    机器学习十大算法(二)
    机器学习十大算法(一)
    django传值出现二进制乱码(基于python3)
    解决mysql的动态添加字段以及数据的方法(基于python3.6)
    odoo权限控制
    win32service的解决办法(pywin32)
  • 原文地址:https://www.cnblogs.com/Pikdays/p/5739795.html
Copyright © 2011-2022 走看看