RunTime的使用-Category中增加实例变量

很久没遇到问题了,今天写类目的时候发现,在我们所创建的类目(Category)中 只能写方法不能写实例变量以及属性,但是这无疑非常不方便,于是这里用到RunTime 这样就能在类目中对属性进行赋值了。
下面我们介绍一个很巧妙的方法来解决:使用runtime库的 objc_setAssociatedObject / objc_getAssociatedObject 函数来解决。
这里只用到RunTime的2个方法,还有其他的方法。
通过这相中方法,明眼人可以看到有set 与 get 的关键字  也就是说一个是设置一个是取值  ,通过这种方法来模拟生成属性。

代码:
在.h文件中正常的声明一个属性,不要太浮夸
@property (nonatomic,retain)ZbarViewController *readerVC;

然后在.M中包含RunTime的头文件
#import <objc/runtime.h>
然后这步骤非常重要 我们需要一个关联的时候的Key来使用,这个Key是用来存储用的
//常规用来标注的Key 万年不变三种写法
1、static void *strKey = &strKey;
2、static NSString *strKey = @"strKey"; 
3、static char strKey;
这里我用第三种
 
static char AddressKey;

之后开始调用RunTime的方法
//设置值
- (void)setAlloc:(ZbarViewController *)zBar
{
    objc_setAssociatedObject(self, &AddressKey, zBar, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

objc_setAssociatedObject的方法,这个方法有四个参数,分别是:源对象(self),关联时的用来标记是哪一个属性的key(AddressKey)(因为你可能要添加很多属性),关联的对象(zBar)和一个关联策略(我前面声明属性用的是retain 所以这里用的是retain)。 
关联策略是一个枚举值 
enum { 
OBJC_ASSOCIATION_ASSIGN = 0, //关联对象的属性是弱引用 
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, //关联对象的属性是强引用并且关联对象不使用原子性OBJC_ASSOCIATION_COPY_NONATOMIC = 3, //关联对象的属性是copy并且关联对象不使用原子性
OBJC_ASSOCIATION_RETAIN = 01401, //关联对象的属性是copy并且关联对象使用原子性 
OBJC_ASSOCIATION_COPY = 01403 //关联对象的属性是copy并且关联对象使用原子性};
 
//取值
- (ZbarViewController *)get
{
    return objc_getAssociatedObject(self, &AddressKey);
}

然后初始化的方法  跟取值的方法分别为
 [self setAlloc:[ZbarViewController new]];   //调用set
    [self get].readerDelegate = self;    //调用Get 
这样就能在类目中使用属性了。

时间: 2024-10-14 02:48:38

RunTime的使用-Category中增加实例变量的相关文章

能否向编译后得到的类中增加实例变量?能否向运行时创建的类中添加实例变量?为什么

不能向编译后得到的类中增加实例变量!能向运行时创建的类中添加实例变量! 因为编译后的类已经注册在runtime中,类结构体中的objc_ivar_list 实例变量的链表和instance_size实例变量的内存大小已经确定,同时runtime 会调用class_setIvarLayout 或 class_setWeakIvarLayout来处理strong weak引用,所以不能向存在的类中添加实例变量. 运行时创建的类是可以添加实例变量,调用 class_addIvar 函数,但是得在调用 

ruby中的实例变量和类变量

定义很简单:实例变量@开头,类变量@@开头 看了一些文章和书,目前了解到的(其实还是不太懂,先记着吧,错了再改): 类变量:可以在类方法和类实例方法中访问,也能被子类继承,并且子类修改之后,父类的值也会更改. 不同的子类都共享这个一个数值,包括子类的实例,都可以来修改这一个值.就理解成:不管自己还是子类的,什么函数都可以访问,也都可以改,改了之后也是大家共享. 实例变量:能被类方法访问,不能被继承,子类中赋值不会影响父类. 子类如果修改了,其实是不是重新定义了一下又赋了新的值? 这个其实更像应该

如何保证一个类中的实例变量不被改变

如题,如果在一个对象中的实例属性不能被改变,需要设置成不可变量的时候采用如下方法:1.将类定义成final类型 2.将实例变量定义成final类型 3.将实例变量的set方法去除 4.将在构造方法中克隆一份数据设置给实例变量 5.将在get方法中将实例变量克隆一份赋值返回给用户 public final class Demo{ private final Date start; private final Date end; public Demo(Date start,Date end){ t

JAVA中构造函数的参数传递给类中的实例变量

1 class VolcanoRobot1 2 { String status; 3 int speed; 4 float temperature; 5 VolcanoRobot1(int speed,float temperature) 6 { if(temperature > 660) 7 { status = "returning home"; 8 speed = 5; 9 temperature = 780; 10 } 11 } 12 void showAttribute

【java基础知识】【类中的实例变量和方法】

当创建一个类的时候, 它其中的变量如果已经被初始化的话,那么就会有一个初始值. 例如: Handler mHandler = new Handler() { public void handleMessage(Message msg) { selectorDialog.cancel(); if (msg.what == 1) { newsList = (List<News>) msg.obj; listViewAdapter = new MainListViewAdapter(NewsMain

ruby中实例变量、类变量等等的区别和联系

ruby的变量有局部变量,全局变量,实例变量,类变量,常量. 1.局部变量 局部变量以一个小写字母开头或下划线开头 局部变量有局部作用域限制(比如一个block内),它的作用域起始于声明处,结束于该声明所在的块.方法定义.类/模块定义的结尾.大家在写代码时经常这样写: irb(main):001:0> i=123    ---------- 这里的i就是局部变量 =>123 irb(main):002:0> s="hi"   ---------- 这里的s就是局部变量

JVM存储位置分配——java中局部变量、实例变量和静态变量在方法区、栈内存、堆内存中的分配

Java中的变量根据不同的标准可以分为两类,以其引用的数据类型的不同来划分可分为“原始数据类型变量和引用数据类型变量”,以其作用范围的不同来区分可分为“局部变量,实例变量和静态变量”. 根据“Java中的变量与数据类型”中的介绍,“变量是在内存中分配的保留区域的名称.换句话说,它是一个内存位置的名称”,也就是说我们通过这个变量名字就可以找到一个指向这个变量所引用的数据的内存指针,根据变量的类型我们可以知道这个指针之后的几个字节里存储了这个变量所引用的数据. 所以,了解变量在方法区.栈内存.堆内存

JNI/NDK开发指南(七)——C/C++访问Java实例变量和静态变量

转载请注明出处:http://blog.csdn.net/xyang81/article/details/42836783 在上一章中我们学习到了如何在本地代码中访问任意Java类中的静态方法和实例方法,本章我们也通过一个示例来学习Java中的实例变量和静态变量,在本地代码中如何来访问和修改.静态变量也称为类变量(属性),在所有实例对象中共享同一份数据,可以直接通过[类名.变量名]来访问.实例变量也称为成员变量(属性),每个实例都拥有一份实例变量数据的拷贝,它们之间修改后的数据互不影响.下面看一

实例变量和局部变量

java中的实例变量:编辑 含义: 实例变量:定义在类中但在任何方法之外.(New出来的均有初始化)[1] 与局部变量的异同: 局部变量:定义在方法之中的变量. 1. 局部变量要先赋值,再进行运算,而实例变量均已经赋初值.(这是局部变量和实例变量的一大区别) 2. 实例变量的对象赋值为null. 3. 局部变量不允许范围内定义两个同名变量.实例变量的作用域在本类中完全有效,当被其他的类调用的时候也可能有效. 4. 实例变量和局部变量允许命名冲突.