Утечка памяти в ядре iOS 5.1 - PullRequest
0 голосов
/ 28 марта 2012

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

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;
    }
}

Свойство location определяется как класс управляемого объекта сущности.

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);

Я не получаю утечку памяти. Почему это так?

1 Ответ

0 голосов
/ 28 марта 2012

Спасибо Инафцигеру за то, что он указал мне правильное направление. В итоге мне пришлось создать собственный класс 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

и я обновил свой View Controller следующим образом:

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

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

...