为什么Objective-C对象存储在堆上而不是栈上

一、什么是栈对象和堆对象

在Objective-C中,对象通常是指一块有特定布局的连续内存区域。我们通常这样创建一个对象

NSObject *obj = [[NSObject alloc] init];

这行代码创建了一个NSObject类型的指针obj和一个NSObject类型的对象,obj指针存储在栈上,而其指向的对象则存储在堆上(堆对象)

目前OC并不支持直接在栈上创建对象(栈对象),但可以通过如下方式间接的创建

struct {
Class isa;
} fakeNSObject;
fakeNSObject.isa = [NSObject class];

NSObject *obj = (NSObject *)&fakeNSObject;
NSLog(@"%@", [obj description]);

二、栈对象优缺点

1、优点

  • 速度
    在栈上创建对象是非常快的,因为很多东西在编译时就确定了,运行时分配空间几乎不耗时;相对而言在堆上创建对象就非常耗时。
  • 简单
    站对象的生命周期是确定的,对象出栈以后就会被释放,不会存在内存泄漏,但这同样也是栈对象的最大缺点。

2、缺点

  • 生命周期固定
    OC变量有效范围是由“{}”包含的块来决定的,也就是说找对象的生命周期仅限于其所在的块里,出了块立马会被释放,一个对象被创建以后有可能会通过方法调用传递到别的方法,当找对象的创建方法返回时,栈对象会被一起pop出栈而释放,导致其没法在别处被继续持有。此时retain操作会失效,除非用copy方法在想持有该栈对象的地方重新拷贝一份属于自己的站对象。
    因此,栈对象会给对象的内存管理造成巨大的麻烦。
  • 空间
    现在操作系统的栈和线程绑定,而栈空间是有限的,具体如下:
512 KB (secondary threads)
8 MB (OS X main thread)
1 MB (iOS main thread)

因此对象如果都在栈上创建不太现实,而堆只要物理内存不警告可以无限使用。
综合以上优缺点,OC选择用堆存储对象。

三、真的没有对象吗

实际上OC里的block却是栈对象,因此栈对象面临的问题在block身上一个都不少,但由于block是仅有的特殊对象,大家对他的特殊性都已经习惯了。
另外,根据前面所说,栈对象的有效区域仅限于其所在的块,因此像下面的代码就无法输出期望的结果:

void (^block)();
if(x)
{
block = ^{ printf("x\n"); };
}
else
{
block = ^{ printf("not x\n"); };
}
block();

原文链接:http://foggry.com/blog/2017/02/06/wei-shi-yao-objective-c-dui-xiang-cun-chu-zai-dui-shang-er-bu-shi-zhan-shang/

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,405评论 30 472
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,498评论 11 349
  • 禅与 Objective-C 编程艺术 (Zen and the Art of the Objective-C C...
    GrayLand阅读 5,596评论 1 10
  • 凌晨一点微信通知闪出来,在王者峡谷团战的我杀红了眼,关键时刻挡住视野,屏幕一暗:You have been sla...
    瓷苏阅读 2,047评论 0 0
  • 刺 文/陆纤橙 提笔的原因大概是因为我想怀念我生命中出现过的妳。 三岛由纪夫说过:也许是天生懦弱的关系,我对所有的...
    komolebi_kay阅读 3,301评论 0 0

友情链接更多精彩内容