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

Objective-C can be mixed to some extent with C ++ and can be called to each other . But Objective-C objects are still more or less managed manually, and the RAII idiom is completely absent from the language. I wonder if it is possible to control the lifetime of Objective-C objects using C ++ smart pointers. Especially now that both boost scoped_ptr and shared_ptr have been added to the C ++ 11 standard

+6
source share
1 answer

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

I think this seems to answer your question. Since Objective-C objects are counted by reference, they already execute target smart pointers created for: divorcing or linking the lifetime of an object from the scope of the method in which it is contained. scoped_ptr can be recreated with autoplay pools and shared_ptr with -retain - -release or strong links.

But to say no is boring. If you really want to combine Objective-C and C ++ like this, we need to first loosen the definition of "Objective-C object". The runtime recognizes something with isa sitting as its first member as an object, and we can use this and write a simple C ++ class with the corresponding object interface so that it can be sent to the message:

 @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 

Now we can create an instance of our C ++ object and wrap it in a smart pointer, which I intend to divide 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 out of scope. } int main(int argc, const char **argv) { func(); return 0; } 

As expected, this prints:

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

to the console.

If needed, the destructor can be equipped to call -dealloc to simulate the proper destruction of the object, but I hope you see that all this is completely optional, especially when the ARC gets smarter with each version of CLANG.

+13
source

All Articles