2012-03-27 13 views
0

Ich versuche, Core Data-Aufrufe für jede Core Data-Entität in eine Helper-Klasse zu zentralisieren. Jede Helper-Klasse enthält die Methoden fetch, update und insert der Entität. Für eine Einheit Hilfsklasse, erhalte ich einen Speicherverlust, wenn ich an dieser Linie das Anwendungsprofil:iOS 5.1 Core Data Memory Leak

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

ARC eingeschaltet ist und das Leck erscheint nach der Ansicht entladen wurde.

Hier sind die zugehörigen Viewcontroller und Helper Class Code:

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

Die Lage Eigenschaft ist definiert als die verwaltete Objektklasse des Unternehmens.

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 

Ich kann nicht herausfinden, warum der Speicherverlust dort auftritt. Irgendwelche Ideen?

UPDATE # 1:

Wenn ich ersetzen diese:

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

mit diesem:

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

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

ich nicht bekommen, den Speicherverlust. Warum das?

+1

Klingt wie ein Retain-Zyklus: Machen Sie "Point.title" und "Point-Untertitel" schwache Referenzen? – lnafziger

+0

haben Sie versucht, den statischen Analysator einzuschalten? – Pochi

+0

@Inafziger: Wie mache ich die Title und SubTitle Eigenschaften von MKPointAnnotation zu einer schwachen Referenz? – Joshua

Antwort

0

Danke an Inafziger dafür, dass er mich in die richtige Richtung weist. Ich mit endete, um eine benutzerdefinierte MKAnnotation Klasse zu erstellen, wie so:

#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 

und ich wie so meinen View-Controller aktualisiert:

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

die benutzerdefinierte Annotation-Klasse auf diese Weise Durch die Implementierung, löste es das Problem des Speicherlecks. Ich bin immer noch nicht 100% ig sicher, wieso Instruments auf das Core Data-Call hingewiesen hat. Vielleicht, weil das NSManagedObject dort entstanden ist und das nicht richtig veröffentlicht wurde?