Managing objective-C objects with c++ std::unique_ptr<> or std::shared_ptr<>

前端 未结 1 1706
隐瞒了意图╮
隐瞒了意图╮ 2021-02-03 12:52

Objective-C can be mixed with c++ to some extent and can be called to each other. But Objective-C objects still are more or less manually managed, and RAII idiom is entirely abs

相关标签:
1条回答
  • 2021-02-03 13:25

    But Objective-C objects still are more or less manually managed, and RAII idiom is entirely absent from the language.

    I think this would seem to answer your question anyhow. Because Objective-C objects are reference counted, they already fulfill the purpose smart pointers were created for: to divorce or tie the lifetime of an object from the scope of the method it's contained in. scoped_ptrs can be recreated with autorelease pools, and shared_ptrs with -retain--release or strong references.

    But saying no is boring. If you really want to mingle Objective-C and C++ like this, we'll need to first loosen the definition of "Objective-C object". The runtime recognizes anything with an isa sitting as its first member as an object, and we can take advantage of that and write a simple C++ class with a corresponding object interface so it can be messaged:

    @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
    

    We can now instantiate an instance of our C++ object and wrap it in a smart pointer, which I'm going to purposefully split into two methods to illustrate the lifetime of the object:

    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;
    }
    

    As one would expect, this prints:

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

    to the console.

    If need be, the destructor could be outfitted to call through to -dealloc to simulate proper object destruction, but I hope you see that all of this is just wholly unnecessary, especially with ARC getting smarter with each release of CLANG.

    0 讨论(0)
提交回复
热议问题