Search code examples
iosobjective-cautomatic-ref-countingretain

Returning object keeps incrementing retainCount


I have a class which inherits from an interface

@interface MyClass : NSObject <IMyClass> {
   NativeCppObject* _myInternalObj;
}

-(id) initWithInternalObj:(NativeCppObject*) myInternalObj;

@end

Then I have a factory class that creates this object

-(id<IMyClass>) createMyClass:(NSString*)myInternalObjParameter
{

  NativeCppObject* nativeObj = new NativeCppObject(...);  
  MyClass ret = [[MyClass alloc] initWithInternalObj:nativeObj];
  return ret;
}

Now the problem that I have is when I chain those calls from createMyClass return value, the returned ret keeps getting referenced and never released. At the end of my chain, I get like 5 retain counts which prevents my object from dealloc correctly.

those calls are like

@implementation MyClassFactory
+(id<IMyClass>) createMyClass:(NSString*) param
{
  return [gFactory createMyClass:param];
}
@end

gFactory is a static id. I know this is not the best practice but at the moment it cannot be trivially changed.

When calling createMyClass from MyClassFactory, the retain count is like 3. Wrapping this into other "factories" just makes more calls to retain and no new call to release. I don't get why this happens.

EDIT:

This is weird. While stepping in the code, I hit "return ret" twice. retain seems to be called twice as well.

EDIT2:

I have a class that needs this factory. In fact this is a test case so some code aims to be generic

-(id<IMyClass>) setupMyObjectAndStuff
{
  NSString* param;
  return [self setupMyObjectAndStuff:param];
}


-(id<IMyClass>) setupMyObjectAndStuff:(NSString*) param
{
  return [MyClassFactory createMyClass:param];
}

Then in my main function, after calling

id<IMyClass> myClass = [self setupMyObjectAndStuff];

MyClass retain will have been called like 3 or 4 times and release will only have been called once or twice.


Solution

  • Turns out that my objects were not wrapped in @autoreleasepool{ ... }

    Changing the calling code to :

    @autoreleasepool{
      id<IMyClass> myClass = [self setupMyObjectAndStuff];
      // ... snip ...
      myClass = nil;
    }
    

    cause the objects to be deallocated as soon as there were no more references to them. Instruments was correctly showing the number of retainCount and all but one of those were autorelease retains.