用C++的std::unique_ptr<>或std::shared_ptr<>来管理Objective-C对象

8

Objective-C可以在一定程度上与C++混合使用,彼此调用。但是Objective-C对象仍然在很大程度上是手动管理的,并且RAII习惯用语完全不存在于该语言中。我想知道是否可能使用c++智能指针来管理Objective-C对象的生命周期。特别是现在C++11标准已经添加了boost scoped_ptrshared_ptr


我的 C++ 知识比 Objective-C 少得多,所以我可能完全误解了你的问题。但是,如果你有自动引用计数(ARC),为什么需要针对 Objective-C 对象使用 C++ 智能指针呢? - Martin R
ARC要求显式地发送释放消息。在C++中,当本地实例变量超出范围时(即使用它的函数返回或抛出异常),会发送相应的减量消息。 - diffeomorphism
1
但是使用ARC,编译器会将必要的保留/释放消息插入到编译后的代码中。因此,从程序员的角度来看,如果一个对象超出了其作用域,它将自动释放。 - Martin R
1个回答

14
但是Objective-C对象仍然或多或少地需要手动管理,并且RAII习惯在该语言中完全不存在。
我认为这似乎已经回答了你的问题。因为Objective-C对象是引用计数的,它们已经实现了智能指针被创建的目的:将对象的生命周期与其包含的方法的作用域分离或绑定。可以使用autorelease池重新创建scoped_ptr,使用-retain--release或strong引用创建shared_ptr。
但是说“不”很无聊。如果您真的想像这样混合使用Objective-C和C++,我们需要首先放松“Objective-C对象”的定义。运行时识别任何具有作为其第一个成员的isa的对象,并且我们可以利用这一点编写一个简单的C++类,具有相应的对象接口,以便可以发送消息:
@interface CFIObject : NSObject
- (void)doSomething;
@end

struct CFIObject_cxx {
    Class isa;
public:
    CFIObject_cxx() : isa([CFIObject class]) {}
~CFIObject_cxx() { printf("I'm dying!"); }
};

@implementation CFIObject
- (void)doSomething {
    NSLog("I did something.");
}
@end
我们现在可以实例化一个 C++ 对象并将其包装到智能指针中,我会故意将它分成两个方法来说明对象的生命周期。
void func() {
    // Instantiate a smart pointer with our fake object.
    std::unique_ptr<CFIObject_cxx> cppObj (new CFIObject_cxx());
    id obj = (__bridge id)(cppObj.get());
    // The runtime thinks we're an object.
    [obj doSomething];
    // aaaand, it's out of scope.
}

int main(int argc, const char **argv) {
    func();
    return 0;
}

正如人们所期望的那样,这将打印:

2013-12-22 17:23:22.681 Test[77528:303] I did something
I'm dying!

如果需要,析构函数可配置为调用 -dealloc 以模拟正确的对象销毁,但我希望您看到所有这些都是完全不必要的,特别是随着 CLANG 的每个版本发布,ARC 变得越来越智能。

输出至控制台。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接