常用的底层语法(objc_get,class_get,_cmd,objc_msgSend)
一,关联 objc_get
1)建立关联:objc_setAssociatedObject;该函数需要四个参数:源对象,关键字,关联的对象和一个关联策略;当源对象销毁,关联的对象也会被销毁
源对象: 即绑定者
关键字: 是一个void类型的指针。每一个关联的关键字必须是唯一的。通常都是会采用静态变量来作为关键字
关联的对象: 绑定到源对象身上的对象
关联策略: 表明了相关的对象是通过赋值,保留引用还是复制的方式进行关联的;还有这种关联是原子的还是非原子的。这里的关联策略和声明属性时的很类似。这种关联策略是通过使用预先定义好的常量来表示的。OBJC_ASSOCIATION_ASSIGN、OBJC_ASSOCIATION_RETAIN_NONATOMIC、OBJC_ASSOCIATION_COPY_NONATOMIC等
2)获取相关联对象:objc_getAssociatedObject:该函数需要两个参数:源对象,关键字
3)断开关联:断开关联是使用objc_setAssociatedObject函数,传入关联的对象为nil值即可。
使用函数objc_removeAssociatedObjects可以断开所有关联。通常情况下不建议使用这个函数,因为他会断开所有关联。只有在需要把对象恢复到“原始状态”的时候才会使用这个函数。
例子:
static char objKey;
NSArray * array =[[NSArray alloc] initWidthObjects:@"One", @"Two", @"Three", nil];
objc_setAssociatedObject(array, &objKey, @“对象”, OBJC_ASSOCIATION_RETAIN);
NSString * associatedObject = (NSString *)objc_getAssociatedObject(array, &objKey);
二,class_get
1)获得实例方法: Method m1 = class_getInstanceMethod([对象 class], @selector(对象方法));
2)获得类方法: Method m2 = class_getClassMethod([类 class], @selector(类方法));
3)方法互调: method_exchangeImplementations(m1, m2); 即执行方法m1变成执行是m2,执行方法m2变成执行是m1
例子:
- Person * p1 = [[Person alloc] init];
- Method m1 = class_getInstanceMethod([p1 class], @selector(对象方法));
- Method m2 = class_getClassMethod([Person class], @selector(类方法));
- NSLog(@"测试前:");
- [p1 对象方法];
- [Person 类方法];
- method_exchangeImplementations(m1, m2);
- NSLog(@"测试后:");
- [p1 对象方法];
- [Person 类方法];
输出:
- 2015-11-04 13:37:08.539 02-runtime[2776:69899] 测试前:
- 2015-11-04 13:37:08.539 02-runtime[2776:69899] this is a 对象方法 method
- 2015-11-04 13:37:08.539 02-runtime[2776:69899] this is a 类方法 method
- 2015-11-04 13:37:08.540 02-runtime[2776:69899] 测试后:
- 2015-11-04 13:37:08.540 02-runtime[2776:69899] this is a 类方法 method
- 2015-11-04 13:37:08.540 02-runtime[2776:69899] this is a 对象方法 method
三,_cmd的用法
_cmd在Objective-C的方法中表示当前方法的selector,正如同self表示当前方法调用的对象实例。NSStringFromSelector(_cmd)得到是方法的名称
例如
static char kExtendVarKey; // 键名
- (void)someCategoryMethod
{
NSString *extendVar = objc_getAssociatedObject(self, &kExtendVarKey);
if(!extendVar){
extendVar = @"someText";
objc_setAssociatedObject(self, &kExtendVarKey, extendVar, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
}
等同于下面代码
- (void)someCategoryMethod
{
NSString *extendVar = objc_getAssociatedObject(self, _cmd);
if(!extendVar){
extendVar = @"someText";
objc_setAssociatedObject(self, _cmd, extendVar, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
}
四,objc_msgSend:该函数至少有两个参数:objc_msgSend(消息的接受者, selector, param1, param2, …);
1)概念:其实每个类中都有一张方法列表去存储这个类中有的方法,当发出objc_msgSend方法时候,就会顺着列表去找这个方法是否存在,如果不存在,则向该类的父类继续查找,直到找到位置。如果始终没有找到方法,那么就会进入到消息转发机制;objc_msgSend被分为2个过程:1)在cache中寻找SEL。2)在MethodTable寻找SEL。
例子
id returnValue = [someObject messageName:parameter]; ======》 id returnValue = objc_msgSend(someObject,@selector(messageName),paramter)
Id returnValue = [super messageName:parameter]; ======》 id returnValue = objc_msgSendSuper(someObject,@selector(messageName),paramter)
常用的底层语法(objc_get,class_get,_cmd,objc_msgSend)的更多相关文章
- linux下常用语言的语法检查插件整理
linux下常用语言的语法检查插件 可以结合vim语法检查插件syntastic使用,具体请参考syntastic使用说明 如php,sql,json,css,js,html,shell,c等语法插件 ...
- Freemaker FTL指令常用标签及语法
https://blog.csdn.net/pengpengpeng85/article/details/52070602 FTL指令常用标签及语法 注意:使用freemaker,要求所有标签必须闭合 ...
- re 模块 常用正则表达式符号 最常用的匹配语法
常用正则表达式符号1 '.' 默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行 '^' 匹配字符开头,若指定flags MULTILINE, ...
- update中加入select最常用的update语法
update中加入select最常用的update语法 (转) (2010-08-20 11:40:16) 转载▼ 标签: it 分类: SQL 最常用的update语法是:UPDATE <ta ...
- 【知识库】-数据库_MySQL常用SQL语句语法大全示例
简书作者:seay 文章出处: 关系数据库常用SQL语句语法大全 Learn [已经过测试校验] 一.创建数据库 二.创建表 三.删除表 四.清空表 五.修改表 六.SQL查询语句 七.SQL插入语句 ...
- FTL指令常用标签及语法
FTL指令常用标签及语法注意:使用freemaker,要求所有标签必须闭合,否则会导致freemaker无法解析. freemaker注释:<#-- 注释内容 -->格式部分,不会输出 - ...
- golang: 常用数据类型底层结构分析
虽然golang是用C实现的,并且被称为下一代的C语言,但是golang跟C的差别还是很大的.它定义了一套很丰富的数据类型及数据结构,这些类型和结构或者是直接映射为C的数据类型,或者是用C struc ...
- grep,awk和sed的常用命令和语法
Grep的常用命令语法 1. 双引号引用和单引号引用在g r e p命令中输入字符串参数时,最好将其用双引号括起来.例如:“m y s t r i n g”.这样做有两个原因,一是以防被误解为 s h ...
- 常用的ement语法
缩写语法: 介绍:Emmet 使用类似于 CSS 选择器的语法描述元素在生成的文档树中的位置及其属性. 声明:第一次写博客大家多多关照,如有错误或者需要补充的请到评论里留言,谢谢大家! 快速生成htm ...
随机推荐
- OSG 中 相交測试 模块 工作流程及原理
主要涉及三个类: 1. osgUtil::PolytopeIntersector // 详细不同算法实现类 2. osgUtil::IntersectionVisitor //用来遍历节点树的每一个节 ...
- hdu 2918(IDA*)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2918 思路:这道题与前面几道类似,可以说是被秒杀了!!!构造启发式函数h()=(cnt+3)/4(cn ...
- UNMET PEER DEPENDENCY @angular/common@2.3.1
install of angular-cli results in unmeet peer dependencies. OSX 10.11.6node v6.9.1npm v3.10.8 [sudo] ...
- C++引用具体解释
引用是C++中新出现的.有别于C语言的语法元素之中的一个. 关于引用的说明,网络上也有不少.可是总感觉云遮雾绕,让人印象不深刻. 今天我就来深入解释一下引用.并就一些常见的观点进行说明,最后附带代码演 ...
- XCODE5 真机測试
原文地址: http://my.oschina.net/u/1245365/blog/196420 亲測 可用 ios申请真机调试( xcode 5)具体解析 摘要 我们做ios项目时.模拟器仅仅能 ...
- ios常用第三方库git下载地址
本文转载至 http://blog.csdn.net/cerastes/article/details/38348599 iOS第三方库下载常用git 1.FMDB https://github.co ...
- GIF动画录制工具(写教程时用的比较小巧的gif工具)
1 软件小巧实用,只有1m 2 gif效果还可以 3 绿色,无需安装 很多地方能下载,百度就行. 下载地址: http://www.downxia.com/downinfo/41427.html
- c#基础 第五讲
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- 【BZOJ2699】更新 动态规划
[BZOJ2699]更新 Description 对于一个数列A[1..N],一种寻找最大值的方法是:依次枚举A[2]到A[N],如果A[i]比当前的A[1]值要大,那么就令A[1]=A ...
- 使用Mac App Store更新、下载软件时出现未知错误的解决方法
很多果迷在使用 Mac App Store 更新/下载软件时,可能都曾被”未知错误”困扰过,怎么解决也不行.然而,过一段时间不知道做了什么又自己好了.今天我们提供两个解决这个问题的方法,下次遇到这个问 ...