Question

I've got some code like this:

@interface MyTimer : NSObject
- (int)getValue;
@end

@interface TimerHolder : NSObject {
    ExternalControl* m_externalControl;
}
@property (retain, nonatomic) MyTimer* timer;
@end

class ExternalControl {
    __unsafe_unretained TimerHolder* m_holder;
public:
    ExternalControl(TimerHolder* holder) : m_holder(holder);
    int getTimer() { return [m_holder.timer getValue] };
};

The method ExternalControl::getTimer() is called very frequently. During profiling, I noticed that during a call to getTimer(), obc-j also calls objc_retain and objc_release (presumably on m_holder or m_holder.timer), which ends up sucking up a lot of time! Removing __unsafe_unretained didn't make a difference.

By construction, I know that whenever ExternalControl::getTimer() is called, m_holder and its timer will stay alive for the duration of the call, so I think the retains/releases are unnecessary.

Is there any way to prevent them from being called?

I'm using XCode 4.2 with iOS 5 SDK, with ARC enabled. Is ARC responsible and removing it would remove the retains/releases? (I didn't want to spend time re-creating a project without ARC just to test this, before checking with you my friends!)

Was it helpful?

Solution

I can only speak from a non-ARC experience as I haven't used it yet (and not planning it being old school).

However, I have several projects using a C++ library and keeping references to it in the obj-C code. I know for a fact that retain/release isn't called unless explicitly requested.

BTW, I couldn't use Obj-C when linking the C++ library and instead had to use Obj-C++ otherwise the C++ constructor/destructors weren't called as expected. It was just a matter of renaming the .m file into .mm

Hope this help.

OTHER TIPS

If you want to manually handle retain/release for just that class (disable ARC). set the "-fno-objc-arc" compiler flag in the build phases tab for that source file.

The WWDC 2011 sessions on ARC specifically mention that when compiled for debug, ARC retain/releases are not optimized.

If you haven't, try running your code in Release mode and profiling it. You should see a significant difference.

However, I know ARC doesn't take into account the kind of design assumptions you imply when you say "By construction". But, ARC shouldn't be touching your your "__unsafe_unretained" instance variable... are you sure those retain/release calls are being passed a pointer to that?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top