objc直接通过指针访问对象实例变量

我们现在来做一件被认为是very bad的事情,如题所示;无论实例变量是私有的、保护的都可以通过地址访问到,并且还可以修改之。这可以称之为所谓的“超级键值编码”。

首先上代码:

#import <Foundation/Foundation.h>

@interface Foo:NSObject{
    NSString *name;
}
@property int id_num;
@end

@implementation Foo
-(id)init{
    self = [super init];
    if(self){
        name = @"lovely panda";
        _id_num = 11;
    }
    return self;
}

-(NSString *)description{
    return [NSString stringWithFormat:@"%@#%@:%d",[self class],name,self.id_num];
}
@end

typedef unsigned long long ULL;

int main(void){
    @autoreleasepool{
        Foo *f = [Foo new];
        NSLog(@"%@",f);
        void *p = (__bridge void *)f;
        int *offset_id_num = p + 16;
        void *offset_name = p + 8;
        ULL name_addr_val = *(ULL *)(offset_name);
        NSString *name = (__bridge id)(void*)name_addr_val;
        NSLog(@"id_num:%d name:%@",*offset_id_num,name);

        *offset_id_num = 1000000000;
        *(ULL *)offset_name = (ULL)@"hello kitty";
        NSLog(@"f now is %@",f);
    }
    return 0;
}

原理大致如下:
f偏移0的实例变量是isa,接下来依次为name和_id_num,然后就是源代码直接通过地址的读取和设置了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值