iOS 5.1核心数据内存泄漏

时间:2012-03-27 22:39:33

标签: core-data ios5 memory-leaks

我正在尝试将每个Core Data实体的Core Data调用集中到Helper类中。每个Helper类都包含实体的fetch,update和insert方法。对于一个实体帮助程序类,当我在此行描述应用程序时,我收到内存泄漏:

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

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 :(得分: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

我更新了我的View Controller:

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

通过以这种方式实现自定义注释类,它解决了内存泄漏的问题。我仍然不能100%确定为什么仪器将泄漏指向Core Data调用。也许是因为那是NSManagedObject的起源而不是正确发布的内容?