I create an object in each iteration of a for
loop. However the dealloc function is never called. Is it not supposed to be released at each iteration? I am using ARC and I have NSZombies deactivated. I don not see either any circular reference. Running the memory leak instruments from xcode it does not show any leaks, however the pointers memory of the class are never freed and the dealloc
call never done. Any idea why this could happen?
Thank you!
for(int i=0; i<10; i++)
{
//calculate the hog features of the image
HogFeature *hogFeature = [self.image obtainHogFeatures];
if(i==0) self.imageFeatures = (double *) malloc(hogFeature.totalNumberOfFeatures*sizeof(double));
//copy the features
for(int j=0; j<hogFeature.totalNumberOfFeatures; j++)
self.imageFeatures[i*hogFeature.totalNumberOfFeatures + j] = hogFeature.features[j];
}
The HogFeature
class declaration looks like this:
@interface HogFeature : NSObject
@property int totalNumberOfFeatures;
@property double *features; //pointer to the features
@property int *dimensionOfHogFeatures; //pointer with the dimensions of the features
@end
and the implementation:
@implementation HogFeature
@synthesize totalNumberOfFeatures = _totalNumberOfFeatures;
@synthesize features = _features;
@synthesize dimensionOfHogFeatures = _dimensionOfHogFeatures;
- (void) dealloc
{
free(self.features);
free(self.dimensionOfHogFeatures);
NSLog(@"HOG Deallocation!");
}
@end
Finally, the call to obtainHogFeatures
inside the UIImage
category looks like:
- (HogFeature *) obtainHogFeatures
{
HogFeature *hog = [[HogFeature alloc] init];
[...]
return hog;
}
You might want to enclose the inner loop with an @autoreleasepool { ... }
which tells the compiler when to do the disposal, otherwise the pool will only be emptied when control returns to the main loop.
for (i = 0; i < 10; i++) {
@autoreleasepool {
...
}
}
As pointed out by CodeFi in the comments:
This will create a new autoreleasepool for each iteration of the loop, which would destroy each object after the iteration is completed, but would make the program do more work. If you don't mind all the objects hanging around until after the loop is completed, you would put the @autoreleasepool
outside of the outer loop
@autoreleasepool {
for (i = 0; i < 10; i++) {
...
}
}