设为首页 加入收藏

TOP

Runtime的几个小例子(含Demo)(三)
2017-10-13 10:32:58 】 浏览:4637
Tags:Runtime 例子 Demo
Ivar(per, ivv,
@"Mike"); //name属性Tom被强制改为Mike。

NSLog(@"改变之后的person:%@",per); }

点击按钮后,控制台输出:

2016-05-19 22:45:05.125 runtime运行时[1957:34730] 改变前的person:name:Tom age:12
2016-05-19 22:45:05.126 runtime运行时[1957:34730] 改变之后的person:name:Mike age:12

 

4.为person的category类增加一个新属性:

如何在不改动某个类的前提下,添加一个新的属性呢?

答:可以利用runtime为分类添加新属性。

 

iOS中,category也就是分类,是不可以为本类添加新的属性的,但是在runtime中我们可以使用对象关联,为person类进行分类的新属性创建:

①新建一个新的OC类:

 

命名为:PersonCategory ,点击next:

②在出现的新类“person+PersonCategory.h”中,添加“height”:

#import "person.h"
@interface person (PersonCategory) @property (nonatomic,assign)float height; //新属性 @end

“person+PersonCategory.m”类的代码如下: 

#import "person+PersonCategory.h"
#import <objc/runtime.h> //runtime API的使用需要包含此头文件

const char * str = "myKey"; //做为key,字符常量 必须是C语言字符串;

@implementation person (PersonCategory)

-(void)setHeight:(float)height{ 
NSNumber *num = [NSNumber numberWithFloat:height]; 
/* 
第一个参数是需要添加属性的对象; 
第二个参数是属性的key; 
第三个参数是属性的值,类型必须为id,所以此处height先转为NSNumber类型; 
第四个参数是使用策略,是一个枚举值,类似@property属性创建时设置的关键字,可从命名看出各枚举的意义; 
objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
*/ 
objc_setAssociatedObject(self, str, num, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

//提取属性的值: 
-(float)height{ 
NSNumber *number = objc_getAssociatedObject(self, str);
return [number floatValue];
}
@end

接下来,我们可以在ViewController.m中对person的一个对象进行height的访问了,

将第四个按钮关联到ViewController.h添加行为并命名其方法为:“addVariable”:(记得:#import "person+PersonCategory.h")

- (IBAction)addVariable:(UIButton *)sender;

在ViewController.m中的实现如下:

/* 4.添加新的属性*/
- (IBAction)addVariable:(UIButton *)sender { per.height = 12;           //给新属性height赋值
    NSLog(@"%f",[per height]); //访问新属性值
}

点击按钮四、再点击按钮一、二获取类的属性、方法。

2016-05-20 15:39:54.432 runtime运行时[4605:178974] 12.000000
2016-05-20 15:39:56.295 runtime运行时[4605:178974] (Name: name) ----- (Type:@"NSString") 2016-05-20 15:39:56.296 runtime运行时[4605:178974] (Name: _age) ----- (Type:i) 2016-05-20 15:39:57.195 runtime运行时[4605:178974] (Method:func1) 2016-05-20 15:39:57.196 runtime运行时[4605:178974] (Method:func2) 2016-05-20 15:39:57.196 runtime运行时[4605:178974] (Method:setAge:) 2016-05-20 15:39:57.196 runtime运行时[4605:178974] (Method:age) 2016-05-20 15:39:57.196 runtime运行时[4605:178974] (Method:.cxx_destruct) 2016-05-20 15:39:57.197 runtime运行时[4605:178974] (Method:description) 2016-05-20 15:39:57.197 runtime运行时[4605:178974] (Method:init) 2016-05-20 15:39:57.197 runtime运行时[4605:178974] (Method:height) 2016-05-20 15:39:57.197 runtime运行时[4605:178974] (Method:setHeight:)

分析:可以看到分类的新属性可以在per对象中对新属性height进行访问赋值。

获取到person类属性时,依然没有height的存在,但是却有height和setHeight这两个方法;因为在分类中,即使使用@property定义了,也只是生成set+get方法,而不会生成_变量名,分类中是不允许定义变量的。

使用runtime中objc_setAssociatedObject()和objc_getAssociatedObject()方法,本质上只是为对象per添加了对height的属性关联,但是达到了新属性的作用;

使用场景:假设imageCategory是UIImage类的分类,在实际开发中,我们使用UIImage下载图片或者操作过程需要增加一个URL保存一段地址,以备后期使用。这时可以尝试在分类中动态添加新属性MyURL进行存储。

 

5.为person类添加一个新方法;

将第五个按钮关联到ViewController.h,添加行为并命名其方法为:“addMethod”:

- (IBAction)addMethod:(UIBu
首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇iOS UIScrollView的使用 下一篇iOS开发UI篇-tableView在编辑状态..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目