Tutorial :A std::tr1::shared_ptr for Objective C++ on iPhone?



Question:

I am mostly a C++ developer, recently I am writing iPhone applications.

The memory management on iPhone is OK to me, due to resource limitation, it's encouraged to use reference counters rather than deep copy.

One annoying thing is I have to manage the reference counters by myself: alloc means counter = 1; retain means counter++, release means counter--

I wish to write a shared_ptr like class for Cocoa Touch, so I rarely have to manually manipulate the reference counters by myself.

I doubt if there's any existing code for that, and I'd like to hear some advices, today is the 5th day since I started to learn objective c

Thanks.


Solution:1

As long as you learn the memory management rules first, there is no real problem with shared_ptr - it can help you in C++ contexts but doesn't let the ownership questions magically disappear.
shared_ptr supports a custom deallocator so the following:

@interface A : NSObject  - (void)f;  @end    @implementation A  - (void)dealloc { NSLog(@"bye"); [super dealloc]; }  - (void)f { NSLog(@"moo"); }  @end    void my_dealloc(id p) {      [p release];  }    // ...  {      shared_ptr<A> p([[A alloc] init], my_dealloc);      [p.get() f];  }  

... outputs:

moo
bye

... as expected.

If you want you can hide the deallocator from the user using a helper function, e.g.:

template<class T> shared_ptr<T> make_objc_ptr(T* t) {      return shared_ptr<T>(t, my_dealloc);  }    shared_ptr<A> p = make_objc_ptr<A>([[A alloc] init]);  


Solution:2

You forgot case 4

[4] you need to pass a pointer to an object out of a method as the return value.

This is where you need -autorelease.

I suggest you read the memory management rules and write some real code before you attempt this little project so that you can get a feel of how memory management is supposed to work.


Solution:3

Automatic reference counting, coming in iOS 5, will effectively make any pointer to an objective-c object act like a smart pointer. Retain/release calls will be synthesized by the compiler on assign and deallocation, unless you explicitly declare a reference to be weak, in which case they'll be automatically zeroed out when the object is deallocated.

My advice is to wait a couple of months for that. You might be able to put together something similar in the meantime, but I'd recommend against it. For one thing, it'll be ugly. Example:

 smart_ptr<id> array = make_smart_ptr( [NSMutableArray array] );     NSUInteger count = [array count];            // won't work.   count = [array.get() count];                 // works, but yuck.   [array.get() setArray: anotherArray.get()];  // even more yuck.  

Also, if your headers are full of c++ classes, you'll have to compile your entire project in objective-c++, which may cause you problems as objective-c++ isn't 100% compatible with objective-c code, and not all third-party frameworks will work properly with it. And forget about sharing your code with anyone else.

It might be an interesting excercise to make something like this work, but you won't want to actually use it. And watch out for the temptation to recreate your favourite bits of C++ in Objective-C. The languages are very different, and you could spend a lot of time doing that, which is time not spent learning all the great stuff you can do in Objective-C that you can't do in C++.


Solution:4

Resource management in Cocoa can be tricky: some API calls automatically retain a reference and some don't, some return an autoreleased object, some a retained object. By shielding this in a shared_ptr class, you'll more likely to make mistakes. My advice is to first take the "normal" Cocoa route until you're fairly experienced.


Solution:5

Have you looked into [object autorelease]? Perhaps that would make things a bit easier.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »