當前位置:
首頁 > 知識 > Consumed parameters耗用参数

Consumed parameters耗用参数

consumed这个单词我并不能给出很准确的翻译,在这篇文章中,我把Consumed parameters称为耗用参数,它在OC中有着独特的应用场景。

在https://clang.llvm.org/docs/AutomaticReferenceCounting.html#id7这份文档中,讲解了ARC方面的知识,我对Consumed
parameters这一个小模块有很大的疑问,因此在网上查了一些资料,虽然有了一个大概的了解,但是还是有一些不太清楚的地方。

我们先来看一个例子,这个例子来源于上边的那份文档:

void foo(__attribute((ns_consumed)) id x);

我们可以用__attribute((ns_consumed))来修饰某个函数或者方法的参数,但这只是表面上的看法,实际上,它并不是只作用于它修饰的某个参数,而是作用于整个函数或方法

它的一个限制是,只能修饰可retain的对象指针类型,比如id, Class等等,不能修饰int *这样的类型。

上边的两行代码表示foo被标记为consumed。意味着该函数的被调用者希望得到一个+1 retain
count的对象。声明了这个属性后,当传入一个参数时,在函数调用前,ARC会把对该参数做一次retain操作,在该函数结束后再对该参数做一次release操作,这一过程很像函数对局部变量的操作

到这里就产生了第一个疑问?

为什么要对传入的参数做retain,在结束时又release掉?

这个跟参数的生命周期有关,我们在函数中使用了参数,当然希望能够得到这个参数的所有权,并且希望该参数一直存活着。这个内容我会在下边的内容中给出一定的解释。在上边的文档中有这样一段话:

Rationale

这段话指出,上边的操作直接从调用者到被调用者转移了所有权,最常见的一个场景就是传递self参数到init方法之中,这个内容将是本文最重要的内容。一般来说,局部的优化会移除任何额外的retain和release操作,这句话的意思是说,在函数中,某些局部变量不一定都会十分严格的按照retain/release原则来进行操作。调用端将会进行一些必要的合并操作,而被调用端也会对参数做一些额外的操作。

到这里,有了第二个疑问?

在ARC中,为什么self在init方法中是一个consumed parameter?

这个问题我之前是不知道的,它来源于这个提问。init方法被标记为ns_consumes_self。ns_consumes_self说明在方法中遵循上边讲的原则,在方法调用之前先把self做retain操作,结束时做release操作。

User *user = [[User alloc] init];

这是一行非常简单的代码,在调用了alloc后就创建了一个User对象,这个可以在这篇回答中获得证据。返回的对象的retain
count等于1,大家应该记得,凡是通过alloc/new/copy.etc生成的对象,retain count都会+1,那么在这里的init方法中:

self = [super init];if (self) { ... }

self首先被init的调用者做了一次retain操作,此时它的retain count为1,执行完self = [super
init];后,它的retain count为2,直到init返回后,self做了一次release操作,此时它的retain
count为1。**这就完美保证了self在方法中是一直存活的,也保证了能够返回一个retain count为1的对象。

有兴趣可以翻看这个提问中的回答的部分,那哥们说的很详细,再说一点,在以前的MRC时代,代码可以这样写:

- (NSView *)view { //explicit retain-autorelease of +1 variable is +2 -> +1, guaranteed access or nil.

为了正确返回某个对象,先retain再release。

因此在使用consumed的时候,需要注意一下几点:

  • 保证方法的接收者不能为null,因为在方法被调用之前,参会会做retain操作,这样就带来了内存泄漏的问题

  • 传递的参数的个数不能大于方法能够动态处理的个数,否则可能引起未知的后果

  • 谨慎处理静态类型的问题

何为静态类型,何为动态类型?

A *a = [A new];

那么b的静态类型就是B,这个类型是由编译器决定的,而A则是它的动态类型,由运行时决定。

我发现ASDisplayKit的源码极其复杂,估计要花相当多的时间来解读了。不能放弃,加油。


中公优就业IT培训,总有你想学的:http://xue.ujiuye.com

勤工俭学计划,0元学IT!

http://www.ujiuye.com/zt/qgjx/?wt.bd=mmxtt

找工作太难?好汉,让我助你一臂之力!

http://www.ujiuye.com/zt/jyfc/?wt.bd=mmxtt

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 IT优就业 的精彩文章:

TAG:IT优就业 |

您可能感興趣

未完待續:Amazon Business帶你了解工業消耗用品的選品秘籍
樂高 1:1 還原布加迪 Chiron,耗用零件數超 100 萬塊
俄民眾烹飪「全國最大」炒雞蛋,耗用483公斤雞蛋共9030顆
花費10多年,耗用15萬工時的頂級工藝品,200多年前就是國寶
1.5匹的空調開一晚上,會耗用多少度電呢?今天可算知道了
大叔們用糯米修復古城牆,920米城牆耗用50噸糯米,百年堅不可摧
中國最難攻打的城市,日軍為此耗用軍費無數,直到投降也沒能攻打下來
世界海拔最高的古宮殿:宏偉而且豪氣,建造耗用了三十多噸黃金