// 修改isa,本质就是改变当前对象的类名
    object_setClass(self, [XMGKVONotifying_Person class]);


// self动态添加关联
    // id object:给哪个对象添加关联属性
    // key:属性名
    // value:关联值
    //objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
    objc_setAssociatedObject(self, @"observer", observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

// self获取关联
    //objc_getAssociatedObject(id object, const void *key)
    id observer = objc_getAssociatedObject(self, @"observer");


默认情况下,如果是以[object message]的方式调用方法,如果object无法响应message消息时,编译器会报错。但如果是以perform…的形式来调用,则需要等到运行时才能确定object是否能接收message消息。如果不能,则程序崩溃。

通常,当我们不能确定一个对象是否能接收某个消息时,会先调用respondsToSelector:来判断一下。如下代码所示:

if ([self respondsToSelector:@selector(method)]) {
[self performSelector:@selector(method)];
}

摘录其它博客:

@implementation HYBMethodLearn

- (int)testInstanceMethod:(NSString *)name andValue:(NSNumber *)value {
NSLog(@"%@", name);
return value.intValue;
} - (void)getMethods {
unsigned int outCount = ;
Method *methodList = class_copyMethodList(self.class, &outCount); for (unsigned int i = ; i < outCount; ++i) {
Method method = methodList[i]; SEL methodName = method_getName(method);
NSLog(@"方法名:%@", NSStringFromSelector(methodName)); // 获取方法的参数类型
unsigned int argumentsCount = method_getNumberOfArguments(method);
char argName[] = {};
for (unsigned int j = ; j < argumentsCount; ++j) {
method_getArgumentType(method, j, argName, ); NSLog(@"第%u个参数类型为:%s", j, argName);
memset(argName, '\0', strlen(argName));
} char returnType[] = {};
method_getReturnType(method, returnType, );
NSLog(@"返回值类型:%s", returnType); // type encoding
NSLog(@"TypeEncoding: %s", method_getTypeEncoding(method));
} free(methodList);
} + (void)test {
HYBMethodLearn *m = [[HYBMethodLearn alloc] init];
// [m getMethods]; ((void (*)(id, SEL))objc_msgSend)((id)m, @selector(getMethods)); // 这就是为什么有四个参数的原因
int returnValue = ((int (*)(id, SEL, NSString *, NSNumber *))
objc_msgSend)((id)m,
@selector(testInstanceMethod:andValue:),
@"标哥的技术博客",
@);
NSLog(@"return value is %d", returnValue); // 获取方法
Method method = class_getInstanceMethod([self class], @selector(testInstanceMethod:andValue:)); // 调用函数
returnValue = ((int (*)(id, Method, NSString *, NSNumber *))method_invoke)((id)m, method, @"测试使用method_invoke", @);
NSLog(@"call return vlaue is %d", returnValue);
}

给NSMutableArray添加分类

#import "NSMutableArray+Swizzling.h"
#import <objc/runtime.h>
#import <objc/message.h> @implementation NSMutableArray (Swizzling)
+(void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ //NSMutableArray ---->__NSArrayM
Method method=class_getInstanceMethod(objc_getClass("__NSArrayM"), @selector(objectAtIndex:)); Method method2=class_getInstanceMethod(objc_getClass("__NSArrayM"), @selector(fdc_objectAtIndex:)); method_exchangeImplementations(method, method2);
});
}
-(id)fdc_objectAtIndex:(NSInteger)index
{
// NSLog(@"%s",__func__); 千万别加上这句 不然有bug
if (self.count == ) {
NSLog(@"%s can't get any object from an empty array", __FUNCTION__);
return nil;
} if (index > self.count) {
NSLog(@"%s index out of bounds in array", __FUNCTION__);
return nil;
}
return [self fdc_objectAtIndex:index];
}
@end

    Student *obj=[[Student alloc]init];

    NSLog(@"instance         :%p", obj);
NSLog(@"---------------------------------------------");
NSLog(@"class :%p", object_getClass(obj));
NSLog(@"meta class :%p", object_getClass(object_getClass(obj)));
NSLog(@"root meta :%p", object_getClass(object_getClass(object_getClass(obj))));
NSLog(@"root meta's meta :%p", object_getClass(object_getClass(object_getClass(object_getClass(obj)))));
NSLog(@"---------------------------------------------");
NSLog(@"class :%p", [obj class]);
NSLog(@"meta class :%p", [[obj class] class]);
NSLog(@"root meta :%p", [[[obj class] class] class]);
NSLog(@"root meta's meta :%p", [[[[obj class] class] class] class]);
-- ::05.074 测试[:] instance         :0x7fed2276d9c0
-- ::05.075 测试[:] ---------------------------------------------
-- ::05.075 测试[:] class :0x101417060
-- ::05.075 测试[:] meta class :0x101417038
-- ::05.076 测试[:] root meta :0x101c75198
-- ::05.076 测试[:] root meta's meta :0x101c75198
-- ::05.076 测试[:] ---------------------------------------------
-- ::05.076 测试[:] class :0x101417060
-- ::05.076 测试[:] meta class :0x101417060
-- ::05.077 测试[:] root meta :0x101417060
-- ::05.077 测试[:] root meta's meta :0x101417060

类簇

类簇的概念:一个父类有好多子类,父类在返回自身对象的时候,向外界隐藏各种细节,根据不同的需要返回的其实是不同的子类对象,这其实就是抽象类工厂的实现思路,iOS最典型的就是NSNumber。

NSNumber,NSArray,NSDictionary、NSString、NSTimer…这说明大多数的OC类都是类簇实现的;

    NSNumber *intNum = [NSNumber numberWithInt:];
NSNumber *boolNum = [NSNumber numberWithBool:YES];
NSLog(@"intNum :%@", [intNum class]);
NSLog(@"boolNum:%@", [boolNum class]);
NSLog(@"Superclass:%@", class_getSuperclass([boolNum class]));
NSLog(@"Superclass:%@", class_getSuperclass([intNum class]));
-- ::21.166 测试[:] intNum :__NSCFNumber
-- ::21.167 测试[:] boolNum:__NSCFBoolean
-- ::21.167 测试[:] Superclass:NSNumber
-- ::21.167 测试[:] Superclass:NSNumber

运行时c函数的更多相关文章

  1. 利用Objective-C运行时hook函数的三种方法

    版权声明:转载请注明出处:http://blog.csdn.net/hursing 方法一,hook已有公开头文件的类: 首先写一个Utility函数: #import <objc/runtim ...

  2. runtime运行时

    /** * Describes the instance variables declared by a class. * * @param cls The class to inspect. * @ ...

  3. 【原】iOS动态性(五)一种可复用且解耦的用户统计实现(运行时Runtime)

    声明:本文是本人 编程小翁 原创,转载请注明. 为了达到更好的阅读效果,强烈建议跳转到这里查看文章. iOS动态性是我的关于iOS运行时的系列文章,由浅入深,从理论到实践.本文是第5篇.有兴趣可以看看 ...

  4. iOS 运行时runtime控制私有变量以及私有方法

    OC是运行时语言,只有在程序运行时,才会去确定对象的类型,并调用类与对象相应的方法.利用runtime机制让我们可以在程序运行时动态修改类.对象中的所有属性.方法,就算是私有方法以及私有属性都是可以动 ...

  5. Objective C运行时(runtime)

    #import <objc/runtime.h> void setBeingRemoved(id __self, SEL _cmd) { NSLog(@"------------ ...

  6. 【原】iOS动态性(二):运行时runtime初探(强制获取并修改私有变量,强制增加及修改私有方法等)

    OC是运行时语言,只有在程序运行时,才会去确定对象的类型,并调用类与对象相应的方法.利用runtime机制让我们可以在程序运行时动态修改类.对象中的所有属性.方法,就算是私有方法以及私有属性都是可以动 ...

  7. iOS运行时Runtime浅析

    运行时是iOS中一个很重要的概念,iOS运行过程中都会被转化为runtime的C代码执行.例如[target doSomething];会被转化成objc)msgSend(target,@select ...

  8. Objective C运行时(runtime)技术的几个要点总结

    前言:          Objective C的runtime技术功能非常强大,能够在运行时获取并修改类的各种信息,包括获取方法列表.属性列表.变量列表,修改方法.属性,增加方法,属性等等,本文对相 ...

  9. 《转》.NET开源核心运行时,且行且珍惜

    转载自infoQ 背景 InfoQ中文站此前报道过,2014年11月12日,ASP.NET之父.微软云计算与企业级产品工程部执行副总裁Scott Guthrie,在Connect全球开发者在线会议上宣 ...

随机推荐

  1. Java程序设计 实验二 Java面向对象程序设计

    北京电子科技学院(BESTI) 实     验    报     告 课程:Java程序设计 班级:1353  姓名:李海空  学号:20135329 成绩:             指导教师:娄嘉鹏 ...

  2. Yii源码阅读笔记(二十七)

    Theme 类,即一个应用的主题,主要通过替换路径实现主题的应用,里边的方法为获取根路径和根链接,以及应用主题的方法: namespace yii\base; use Yii; use yii\hel ...

  3. PHP多台服务器跨域SESSION共享

    网站业务规模和访问量的逐步发展,原本由单台服务器.单个域名的迷你网站架构已经无法满足发展需要. 此时我们可能会购买更多服务器,并且启用多个二级子域名以频道化的方式,根据业务功能将网站分布部署在独立的服 ...

  4. asp.net如何在前台利用jquery Ajax调用后台方法

    一 :最近因为帮同事开发项目使用到了asp.net,而我又想实现Ajax异步请求....从网上查询了一下资料之后,原来在asp.net中利用Ajax调用后台方法同样很简单,为了便于自己以后查看,特将此 ...

  5. Qunie问题

    Quine 以哲学家 Willard van Orman Quine (1908-2000) 而命名,表示一个可以生成他自己的完全的源代码的程序.编写出某个语言中最简短的 quine 通常作为黑客们的 ...

  6. 如何把自己打造成技术圈的papi酱

    最近半年,一个叫papi酱的平胸女子连续在微博.朋友圈.创业圈刷屏,当之无愧成了中文互联网的第一大网红.呃,你以为我会巴拉巴拉说一堆网工创业的事?NO,今天想借papi酱的话题跟大家一起聊聊程序员如何 ...

  7. java netty之ServerBootstrap的启动

    通过前面的几篇文章,对整个netty部分的架构已经运行原理都有了一定的了解,那么这篇文章来分析一个经常用到的类:ServerBootstrap,一般对于服务器端的编程它用到的都还算是比较的多..看一看 ...

  8. 检测浏览器是否支持cookie方法

    cookie 摘自: http://www.cnblogs.com/fish-li/archive/2011/07/03/2096903.html Cookie是什么? Cookie 是一小段文本信息 ...

  9. Rstudio使用记录

    2016/11/1 目前新建两个project:project1(有两个变量x,y)&&project2(无变量)

  10. 从零开始学Linux[一]:基本命令:系统信息、目录、文件、文件编辑

    摘要:linux基础学习:系统信息.目录.文件查找.文件操作.查看文件内容及大小.软链接.VIM使用. 现在Linux的使用非常普遍.对于一个小白来说,满屏幕的字母,看起来就是一头雾水~   目前由于 ...