博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
运行时c函数
阅读量:4981 次
发布时间:2019-06-12

本文共 5795 字,大约阅读时间需要 19 分钟。

// 修改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 = 0;  Method *methodList = class_copyMethodList(self.class, &outCount);    for (unsigned int i = 0; i < outCount; ++i) {    Method method = methodList[i];        SEL methodName = method_getName(method);    NSLog(@"方法名:%@", NSStringFromSelector(methodName));        // 获取方法的参数类型    unsigned int argumentsCount = method_getNumberOfArguments(method);    char argName[512] = {};    for (unsigned int j = 0; j < argumentsCount; ++j) {      method_getArgumentType(method, j, argName, 512);            NSLog(@"第%u个参数类型为:%s", j, argName);      memset(argName, '\0', strlen(argName));    }        char returnType[512] = {};    method_getReturnType(method, returnType, 512);    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:),                                   @"标哥的技术博客",                                   @100);  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", @11);  NSLog(@"call return vlaue is %d", returnValue);}

 


 

给NSMutableArray添加分类

#import "NSMutableArray+Swizzling.h"#import 
#import
@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 == 0) { 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]);
2016-07-14 10:24:05.074 测试[1145:46819] instance         :0x7fed2276d9c02016-07-14 10:24:05.075 测试[1145:46819] ---------------------------------------------2016-07-14 10:24:05.075 测试[1145:46819] class            :0x1014170602016-07-14 10:24:05.075 测试[1145:46819] meta class       :0x1014170382016-07-14 10:24:05.076 测试[1145:46819] root meta        :0x101c751982016-07-14 10:24:05.076 测试[1145:46819] root meta's meta :0x101c751982016-07-14 10:24:05.076 测试[1145:46819] ---------------------------------------------2016-07-14 10:24:05.076 测试[1145:46819] class            :0x1014170602016-07-14 10:24:05.076 测试[1145:46819] meta class       :0x1014170602016-07-14 10:24:05.077 测试[1145:46819] root meta        :0x1014170602016-07-14 10:24:05.077 测试[1145:46819] root meta's meta :0x101417060

类簇

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

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

NSNumber *intNum = [NSNumber numberWithInt:1];    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]));
2016-07-14 10:30:21.166 测试[1179:51674] intNum :__NSCFNumber2016-07-14 10:30:21.167 测试[1179:51674] boolNum:__NSCFBoolean2016-07-14 10:30:21.167 测试[1179:51674] Superclass:NSNumber2016-07-14 10:30:21.167 测试[1179:51674] Superclass:NSNumber

 

转载于:https://www.cnblogs.com/jingdizhiwa/p/5666417.html

你可能感兴趣的文章
PHP全栈学习笔记15
查看>>
设计模式之原型模式
查看>>
[leetcode]349.Intersection of Two Arrays
查看>>
GNU make manual 翻译( 一百三十一)
查看>>
算法第3章作业
查看>>
EXCEL多列名称组合成一列名称
查看>>
Intent在Android中的几种用法 .
查看>>
改变窗口的位置 (转载)
查看>>
let 与 const 的用法
查看>>
使用HttpClient发送文件流到服务器端
查看>>
python-进程
查看>>
Atom
查看>>
Jenkins-在windows上配置自动化部署(Jenkins+Gitblit)
查看>>
Marvel – 将图像和源文件转换成互动,共享的原型
查看>>
如何给网站瘦身?图文并茂的前端性能优化指南
查看>>
codeforce 6D-6E(dp,线段树)
查看>>
python学习笔记(六)循环
查看>>
[置顶] myEclipse8.5或者eclipse手工安装jd插件(myEclipse8.5或eclipse内直接查看.class文件,jd反编译工具)...
查看>>
MST最小生成树及Prim普鲁姆算法
查看>>
Access连接数据源配置(新手必知)
查看>>