iOS 面试题(1):一个 Objective-C 对象的内存结构是怎样的?

接下来分享的将会是唐老师一系列的iOS面试题,因为之前好几期唐老师都删掉了,说是要出书,所以转载过来,需要的朋友们可以看下,也方便我自己巩固、学习。


转载自:http://mp.weixin.qq.com/s?__biz=MjM5NTIyNTUyMQ==&mid=2709545297&idx=1&sn=a391cf9771ed34a211d4d91724bdbaec&chksm=828f0b8fb5f88299f42bde095fb323fe9ed5fa082b19a451535f069b1db550366a35d6c5e8f7&mpshare=1&scene=1&srcid=0221JIeBGylsHuaG1lwvh5Wn#rd


问题

一个 Objective-C 对象的内存结构是怎样的?

答案

这是一道老题,或许很多人都准备过,其实如果不是被每个公司都考查的话,这道题可以看看候选人对于 iOS 背后底层原理的感兴趣程度。真正对编程感兴趣的同学,都会对这个多少有一些好奇,进而在网上搜索并学习这方面的资料。

以下是本题的简单回答:

如果把类的实例看成一个C语言的结构体(struct),它首先包含的是一个 isa 指针,而类的其它成员变量依次排列在结构体中。排列顺序如下图所示:


为了验证该说法,我们在Xcode中新建一个工程,在main.m中运行如下代码:

#import <UIKit/UIKit.h>

@interface Father : NSObject {    
    int _father;
}
@end@implementation Father

@end

@interface Child : Father {    
int _child;
}
@end

@implementation Child

@end

int main(int argc, char * argv[])
{

  Child * child = [[Child alloc] init];  
  @autoreleasepool {      
       // ...
  }
}

我们将断点下在  @autoreleasepool  处,然后在Console中输入 p *child ,则可以看到Xcode输出如下内容,这与我们上面的说法一致。

(lldb) p *child
(Child) $0 = {
  (Father) Father = {
    (NSObject) NSObject = {
      (Class) isa = Child
    }
    (int) _father = 0
  }
  (int) _child = 0
}
因为对象在内存中的排布可以看成一个结构体,该结构体的大小并不能动态变化。所以无法在运行时动态给对象增加成员变量。

注:需要特别说明一下,通过 objc_setAssociatedObject 和 objc_getAssociatedObject方法可以变相地给对象增加成员变量,但由于实现机制不一样,所以并不是真正改变了对象的内存结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值