昨日的一篇写的__autoreleasing ARC下关于Objective-C二级指针 让我有点不一样的想法 感觉对这一块有点模糊。为什么搞得那么复杂呢,还要显式的去转换才能用呢?
从一个int *开始对比学习吧 (想法的基础)
int inv =20;
int *p = &inv;
NSLog(@"\n--指针变量的地址%p",&p);
NSLog(@"\n--指针指向的int的地址%p",&inv);
NSLog(@"\n--指针指向的地址%p",p);
NSLog(@"\n--指针指向的地址的值%d",*p);
*p =10;
NSLog(@"\n--修改过后指针指向的地址%p",p);
NSLog(@"\n--修改过后指针指向的地址的值%d",*p);
打印结果也就是所*p 的值 操作对应地址的值
直接粗暴来试试
NSObject *o = [[NSObject alloc]init];
NSObject *ob = &o;
*o = [[NSObject alloc]init];
Implicit conversion of an indirect pointer to an Objective-C pointer to 'NSObject *' is disallowed with ARC
所以我们就需要__autoreleasing ARC 的Objective-C二级指针 来进行转换
我们直接打印看看一看究竟为什么不行
而为什么按理论来说是可行的
NSObject *o = [[NSObject alloc]init];
NSLog(@"\n--NSObject指针变量的地址%p",&o);
NSLog(@"\n--指针指向的NSObject的地址%p",o);
打印结果2咦 好家伙 按这个道理 那我可以直接就 *o 不就是isa 那接着就可以骚操作了
对的 但是粗暴可不行 oc按照oc的来 Class o_isa = object_getClass(o);
噢 那跟一开始的想法不咋一样 emmm 再想想办法
不用oc 用 C 操作一下?
void **o_void_isa = (__bridge void *)o;
printf("\n --- *obj %p",*o_void_isa);
printf("\n --- *Class %p\n",o_isa);
打印结果3真不错 还是同样的味道
那行 我直接isa替换 再调个方法试试
MCBlock *tempMCObj = [[MCBlock alloc] init];
void **temp = (__bridge void * )tempMCObj;
NSLog(@"替换前 %@ testBlock这个方法",[o respondsToSelector:@selector(testBlock)] ? @"有":@"没有");
*o_void_isa = *temp;
[o performSelector:@selector(testBlock)];
打印结果4方法调用是实现了 会不会带来其他的问题呢?
修改了它的isa指针 那么存储的信息有一点的变化 接着 它的属性/成员变量的偏移量发生了改变 好像可以强行的加入了成员变量和属性
但是存在一个问题 NSObject 在编译期间就确定了他的大小
(那么改变了isa具体怎么去查找方法 怎么去取变量的内容 其实就是可以理解为规则改变了 按照MCBlock规则的来取变量 那么MCBlock里面就有我们的如图的成员变量和属性 原vcObj是NSObject)
注意但凡涉及到取其成员变量 可能存在访问越界 超出了当初申请的内存空间大小。图中只是打印方法的名字 没有涉及成员变量。
上述可认定为强制类型转换 vcObj 已经变成了MCBlock
如果我们拿同类型进行操作的话那就是我们通过指针的形式返回值这一个目的了(接上篇)
打印结果5
网友评论