zoukankan      html  css  js  c++  java
  • OC-category 为什么不能添加成员变量

    以下的答案是百度的,仅做记录而已:

    1. 利用运行时实际上也不是添加成员变量。已编译的类的内存布局是不变的,Class就是一个结构体,里面的成员不能改变。但是通过运行时可以将一个对象或基础类型变成指定Class对象的一个关联对象,他们两者的内存布局是分开的,与成员变量不同。

    2.关联的并不是在指定Class上,而是指定的对象上,概念上有一定差别。
    objc_setAssociatedObject()这个函数接收四个参数,第一个是需要关联的对象,第二个是索引的一个KEY,第三个是被关联对象,第四个是内存管理类型。
    所以这里运行时会为某个对象设一个关联键值对,通过KEY可以找到对应的关联对象。
    objc_getAssociatedObject(),接收关联对象和KEY提取出被关联对象。

    3.Rumtime的话是黑魔法,滥用起来的话OC会变成JS,动态能力太强,什么都可以通过运行时来改。。但同时也让维护变得非常困难,就像交换方法这种,如果故意恶作剧在一些Foundation里交换了一些常用方法。。这就坑爹了。
    Runloop的话如果不涉及优化的话也不是很常用,通常是通过添加观察者响应Runloop状态的回调从而进行一些操作,例如在Runloop空闲的时候扔一些任务给他做做。



    APP开发更注重是是上层与业务打交道的逻辑。到需要优化的时候再考虑用这些黑魔法去实现。

    4.OC是不能直接修改对象的结构体的成员变量属性,一般做法是先取出对象的结构体变量,修改该取出来的结构体变量里面的成员,再把结构体对象赋值给原来的结构体变量;这个就要弄清@property关键字了,在类中@property关键字会生成私有成员变量,和申明getter setter方法,但是在分类中只会声明getter和setter方法,不会生成成员变量;扩展: 如果在.m中手动实现了setter和getter方法,x-code就不会自动生成@synthesize,也就不会生成成员变量;点语法访问的是getter方法,对象的->调用才是访问的成员变量

    5.如果我们真的需要给category增加属性的实现,需要借助于运行时的两个函数:

    objc_setAssociatedObject
    objc_getAssociatedObject

    6.就category和extension的区别来看,我们可以推导出一个明显的事实,extension可以添加实例变量,而category是无法添加实例变量的(因为在运行期,对象的内存布局已经确定,如果添加实例变量就会破坏类的内部布局,这对编译型语言来说是灾难性的)
  • 相关阅读:
    Linux Shell脚本Ldd命令原理及使用方法
    没有判断好形势,哪怕再多的传感器说有问题,核心的那个几仪表就是在歌舞升平
    JVM
    leetcode第一刷_Count and Say
    html 前台通用表单
    BP神经网络算法学习
    flash的dragonbone插件导入cocos2d的注意事项
    445port入侵具体解释
    google域名邮箱申请 gmail域名邮箱申请(企业应用套件)指南
    SQL性能优化工具TKPROF
  • 原文地址:https://www.cnblogs.com/lyz0925/p/7366761.html
Copyright © 2011-2022 走看看