2012-03-27 58 views
0

我正在尝试将每个核心数据实体的核心数据调用集中到一个助手类中。每个Helper类都包含实体的读取,更新和插入方法。对于一个实体的辅助类,我得到一个内存泄漏时,我在这条线分析的应用程序:iOS 5.1核心数据内存泄漏

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

ARC打开并认为已被卸载后出现的泄漏。

下面是相关联的ViewController和帮助器类代码:

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

我不明白的内存泄漏。这是为什么?

+1

听起来像一个保留周期:让'point.title'和'point.subtitle'弱引用? – lnafziger 2012-03-28 02:47:46

+0

你有没有试过打开静态分析仪? – Pochi 2012-03-28 02:55:58

+0

@Inafziger:如何让MKPointAnnotation的Title和SubTitle属性成为弱引用? – Joshua 2012-03-28 03:03:56

回答

0

感谢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%确定仪器为什么将漏洞指向核心数据呼叫。也许因为那是NSManagedObject的起源,那不正确的发布?