문제

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++) {
        ...
    }
}

다른 팁

The reason the objects are sticking around is because they aren't being released. I don't see the declaration of self.imageFeatures - is this an array? If the features are being put in to an array, they won't be released as long as they remain in the array or the array itself isn't released.

I'm a little confused by the use of the C malloc and (attempted) free calls. There may very well be a motivation here I'm not aware of, but, given what you have provided, here is how I would write this, and I'd be surprised if the deallocs aren't triggered as expected:

    NSMutableArray *features = [[NSMutableArray alloc] init];

    for (int i = 0; i < 10; i++)
    {
        NSArray *hogFeatureArray = [[self image] obtainHogFeatures];
        for (HogFeature *feature in hogFeatureArray)
        {
            [features addObject:hogFeature];
        } 
    }

    [self setImageFeatures:features];

The imageFeatures property is:

@property (nonatomic, retain) NSMutableArray *imageFeatures;

Assuming you've put all your hog feature instances into this imageFeatures array, they will be retained by that imageFeatures array. In order to observe your dealloc in action, one of two things needs to happen: You either need to remove a hog feature from the array, or you need to release the array itself (this would be done by setting the pointer to nil):

[self setImageFeatures:nil] // Previously assigned array now released
[[self imageFeatures] removeAllObjects]; // Works alternatively
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top