ObjC如何通过runtime修改Ivar的内存管理方式(三)

第二次尝试

到了这里,我们已经完全搞清楚了 oc 是如何管理assignweak对象的了,如果你有兴趣也可以去自己尝试破解strong的实现机制,原理一样。接下来我们决定开始对 MCAssignToWeak 进行第二次修改的尝试,这一次,我们需要加入对 delegate 属性的 setter 和 getter 的替换,使之调用正确的方法存取成员变量。

@implementation MCAssignToWeak (fixup)
+ (void)load {...}
- (void)fixup_setDelegate:(id)delegate {
    Ivar ivar = class_getInstanceVariable([self class], "_delegate");
    object_setIvar(self, ivar, delegate);
    [self fixup_setDelegate:delegate]; // 最后调用原实现
}
- (id)fixup_delegate {
    id del = [self fixup_delegate];
    del = objc_loadWeak(&del);
    return del;
}
@end

我们之所以在 fixup_setDelegate: 方法里,调用了 object_setIvar 而不是 objc_storeWeak 方法来设置弱引用到 _delegate,是因为 object_setIvar 里面需要先获取 Ivar 的 offset,然后将加上了偏移后的地址传入到 objc_storeWeak方法,同时 object_setIvar 还可以根据内存修饰符来调用与之相符的内存管理方法,这样写不仅能适应我们当前的assignweak的需要,还可以满足以后其他类型之间互转的需要:

static ALWAYS_INLINE 
void _object_setIvar(id obj, Ivar ivar, id value, bool assumeStrong)
{
    if (!obj  ||  !ivar  ||  obj->isTaggedPointer()) return;

    ptrdiff_t offset;
    objc_ivar_memory_management_t memoryManagement;
    _class_lookUpIvar(obj->ISA(), ivar, offset, memoryManagement);

    if (memoryManagement == objc_ivar_memoryUnknown) {
        if (assumeStrong) memoryManagement = objc_ivar_memoryStrong;
        e
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值