Утечка памяти основных данных iOS 5.1

Я пытаюсь централизовать вызовы Core Data для каждого объекта Core Data в вспомогательном классе. Каждый вспомогательный класс содержит методы выборки, обновления и вставки сущности. Для одного вспомогательного класса сущности я получаю утечку памяти, когда профилирую приложение в этой строке:

NSArray *results = [managedObjectContext executeFetchRequest:request error:&error];

ARC включен и утечка появляется после выгрузки вида.

Вот связанный код ViewController и Helper Class:

ViewController.m:

@synthesize location // and other properties...;

- (void)viewDidLoad
{
    [self loadLocation];
    [super viewDidLoad];
}

- (void)viewDidUnload 
{
    // Set properties to nil here

    [super viewDidUnload];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)loadLocation
{
    if (self.locationID.intValue > 0)
    {
        LocationCoreDataHelper *helper = [[LocationCoreDataHelper alloc] init];
        self.location = [helper selectLocationWithPredicate:[NSString stringWithFormat:@"id = %d", self.locationID.intValue]];

        if(self.location)
        {
            // Create a new coordinate of the user's location
            CLLocationCoordinate2D coord;
            coord.latitude = [self.location.latitude doubleValue];
            coord.longitude =[self.location.longitude doubleValue];

            // Annotate the point with user's information
            MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
            point.coordinate = coord;
            point.title = self.location.title;
            point.subtitle = self.location.subtitle;

            // Add the annotated point
            [mkMap addAnnotation:point];  

            // Set the viewable region of the map
            MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(point.coordinate, 5000, 5000);

            [mkMap setRegion:region animated:YES]; 
        }

        helper = nil;
    }
}

Свойство местоположения определяется как класс управляемых объектов объекта.

LocationCoreDataHelper.m:

@implementation LocationCoreDataHelper

- (id)init
{
    if(self = [super init])
    {
        // Setup the core data manager if needed
        if(managedObjectContext == Nil)
        {
            managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
        }        
    }

    return self;
}

- (Location *)selectLocationWithPredicate:(NSString *)predicateString
{
    NSError *error = nil;

    // Build the entity and request
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Location" inManagedObjectContext:managedObjectContext];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entity];

    if(predicateString)
    {
        // Set the search criteria
        NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];
        [request setPredicate:predicate];
    }

    // Perform the search
    // LEAK HERE
    NSArray *results = [managedObjectContext executeFetchRequest:request error:&error];  

    if(results.count >0)
    {
        return (Location *)[results lastObject];
    }
    else
    {
        return nil;
    }
}

// Other methods here
@end

Я не могу понять, почему там происходит утечка памяти. Любые идеи?

ОБНОВЛЕНИЕ №1:

Если я заменю это:

point.coordinate = coord;
point.title = self.location.title;
point.subtitle = self.location.subtitle;

с этим:

point.coordinate = coord;
point.title = @"Title";
point.subtitle = @"Subtitle";

NSLog(@"%@", self.location.title);

У меня не возникает утечки памяти. Это почему?


person Joshua    schedule 27.03.2012    source источник
comment
Звучит как цикл сохранения: сделать слабые ссылки point.title и point.subtitle?   -  person lnafziger    schedule 28.03.2012
comment
вы пробовали включать статический анализатор?   -  person Pochi    schedule 28.03.2012
comment
@Inafziger: Как сделать свойства Title и SubTitle MKPointAnnotation слабой ссылкой?   -  person Joshua    schedule 28.03.2012
comment
@LuisOscar: Статический анализатор не выдает никаких проблем.   -  person Joshua    schedule 28.03.2012
comment
Ааа, не заметил, что это MKPointAnnotation. В вашем Viewcontroller.m добавьте mkMap = nil к вашему viewDidUnload, и это должно помочь.   -  person lnafziger    schedule 28.03.2012
comment
@Inafziger: я не включил это в код (это плохо), но я устанавливал mkMap=nil для viewDidUnload. Однако ваш предыдущий комментарий указал мне правильное направление, и я добавлю решение ниже. Спасибо за вашу помощь!   -  person Joshua    schedule 28.03.2012


Ответы (1)


Спасибо Inafziger за то, что указал мне правильное направление. В итоге мне пришлось создать собственный класс MKAnnotation следующим образом:

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface MyAnnotation : NSObject <MKAnnotation>

@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy, readonly) NSString *title;
@property (nonatomic, copy, readonly) NSString *subtitle;

- (id) initWithCoordinates:(CLLocationCoordinate2D)paramCoordinates
                     title:(NSString *)paramTitle
                     subTitle:(NSString *)paramSubTitle;

@end

и я обновил свой контроллер представления следующим образом:

MyAnnotation *point = [[MyAnnotation alloc] initWithCoordinates:coord
                                                          title:self.location.title
                                                       subTitle:self.location.subtitle];

Реализовав пользовательский класс аннотаций таким образом, он решил проблему утечки памяти. Я до сих пор не уверен на 100%, почему Instruments указали утечку на вызов Core Data. Возможно, потому что именно здесь возник NSManagedObject, а не то, что выпускалось должным образом?

person Joshua    schedule 28.03.2012