我正在尝试将每个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);
我没有得到内存泄漏。那是为什么?
答案 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的起源而不是正确发布的内容?