2012-03-27 4 views
0

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

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

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

Вот ассоциированная ViewController и код Helper Класса:

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 

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

UPDATE # 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

Звучит как цикл сохранения: Сделайте «point.title» и «point.subtitle» слабыми ссылками? – lnafziger

+0

Вы пытались включить статический анализатор? – Pochi

+0

@Inafziger: Как заставить свойства MKPointAnnotation Title и SubTitle использовать слабую ссылку? – Joshua

ответ

0

Благодаря Инафцигеру, указывая мне в правильном направлении. Я в конечном итоге того, чтобы создать пользовательский класс 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%, почему приборы указали на утечку на вызов Core Data. Возможно, потому, что именно там возник NSManagedObject, и это было не то, что было выпущено должным образом?