Objective-C 是否有 C++11 右值引用和移动语义等效项或者如何实现?

5 c++ objective-c copy-constructor move-semantics c++11

我正在学习 Objective-C。我有这样一个“学术”问题,是向精通现代 C++ (C++11) 的 Objective-C 专家提出的。

在 C++11 中,我经常使用移动语义(使用对临时对象的引用我们可以避免不必要的复制):
什么是移动语义?
http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html

这些链接适用于不熟悉移动语义概念的 Objective-C 编码人员,我感兴趣的是 Objective-C 是否有类似的东西,或者可能有一些方法来实现/模拟它?

jus*_*tin 3

Objective-C 是否有类似的东西,或者可能有一些方法来实现/模拟它?

没有。一旦您理解了您正在使用 Objective-C 处理的抽象层,这就不是什么大问题了。了解对象是引用计数的并且是堆分配的。

现在您可以采用两种方法:

a) 使用 Objective-C++——只需将语言功能与您的内容混合并匹配即可。

b) 使用惯用的 Objective-C。这要追溯到很久以前。一旦您接受对象是引用计数堆分配并且没有办法解决这个问题(使用 clang),那么您就学会以不同的方式处理程序。当然,对所有内容进行引用计数并将其放入堆中是有成本的,但在某些情况下您可以利用这些特性。最显着的用途是使用不可变对象和浅复制。复制std::stringas 对象将导致 SSO 复制或堆分配。复制 anNSString可以简单地返回自身(在增加或不增加引用计数之后,取决于它的字符串类型,它可能还需要在此时创建一​​个具体副本)。同样,这些对象都只是指针,因此您不需要主动关心如何传递对象(值/引用/常量引用/移动)。ObjC 中存在一个简单得多的模型,可以利用。所以这里的设计发生了转变:ObjC 中的“价值主导”更少,而更多的是“有利于不变性和共享”。

在某些情况下,您可以编写一个移动方法。由于常见的框架类不支持这一点,因此使用对象组合通常更有意义。

由于对象是在堆上分配的,因此移动并不是那么重要。精心设计的类会考虑成本,以尽量减少巨大/昂贵的副本,并在内部使用一些有趣的优化。这个习惯用法只是建议您应该采用不同的方法来创建类——它们如何共享数据?什么是可变的?必须复制什么?有时,您可能正在处理大的、可变的/昂贵的数据,移动会很方便,但您通常可以将其放置在共享容器对象中,或者重新考虑对象初始化的语义,以最大程度地减少物理复制(并避免奇怪的情况)对象接口中的语义)。除此之外,我并不认为移动在纯 Objective-C 中经常非常有用。当然,它们对于 C++ 库变得很重要,这些库被设计为利用移动语义并能够在多个内存位置创建对象。如果您确实要移动,您通常会希望将该细节保密或使其变得非常明显(例如,我在渲染管道中这样做是为了最大限度地减少每个过滤器的大量分配)。

您认为这样做有益的例子也将有助于理解您的问题/理由。