我正在使用 NSOperationQueue 和 NSInvocationOperation 在我的 UIViewController 上调用一个方法,然后该方法调用另一个类中的一个方法,该方法反过来解析来自 Web 的 XML 文件并更新一些核心数据托管对象。
这个过程在我第一次运行应用程序时有效,但是当我第二次调用该方法时(再次显示 UIViewController 时),它不会执行 XML 解析器类中的 executeFetchRequest 语句之后的任何行。这是我用来执行的代码:
我有一个 UITableViewController,它在加载时从我的核心数据存储中获取停车场的所有静态信息:
- (void)viewDidLoad
{
NSLog(@"viewDidLoad");
[super viewDidLoad];
southeastCarparks = [[NSMutableArray alloc] init];
southwestCarparks = [[NSMutableArray alloc] init];
northeastCarparks = [[NSMutableArray alloc] init];
northwestCarparks = [[NSMutableArray alloc] init];
carparkLocations = [[NSMutableArray alloc] initWithObjects:southeastCarparks, southwestCarparks, northeastCarparks, northwestCarparks, nil];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"CarparkInfo" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSError *error;
self.carparkInfos = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
for (CarparkInfo *carpark in self.carparkInfos){
if ([carpark.details.region isEqualToString:@"Southeast"]){
[southeastCarparks addObject:carpark];
} else if ([carpark.details.region isEqualToString:@"Southwest"]){
[southwestCarparks addObject:carpark];
} else if ([carpark.details.region isEqualToString:@"Northeast"]){
[northeastCarparks addObject:carpark];
} else if ([carpark.details.region isEqualToString:@"Northwest"]){
[northwestCarparks addObject:carpark];
}
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(loadXMLData)
name:@"appDidBecomeActive"
object:nil];
}
然后当视图出现时,我调用 loadXML 方法访问网络并从 xml 文件中获取最新的停车位信息
- (void) viewDidAppear:(BOOL)animated
{
[self loadXMLData];
NSLog(@"viewDidAppear");
}
- (void) loadXMLData {
NSLog(@"loadXMLData");
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(loadXMLDataWithOperation)
object:nil];
[queue addOperation:operation];
}
- (void) loadXMLDataWithOperation {
xmlParser = [[XMLParser alloc] loadXMLByURL:xmlFileURL];
[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
}
在 XMLParser 类中,我获取传入的 xmlFileURL,从 Web 检索它,解析它,然后尝试更新 Core Data 存储中的可用空间
-(id) loadXMLByURL:(NSString *)urlString
{
_carparks = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
[parser parse];
return self;
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if (![elementName isEqualToString:@"carpark"]){
return;
}
currentCarpark = [Carpark alloc];
NSString *name = [attributeDict objectForKey:@"name"];
currentCarpark.name = name;
NSString *spaces = [attributeDict objectForKey:@"spaces"];
currentCarpark.spaces = spaces;
[self.carparks addObject:currentCarpark];
currentCarpark = nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// set up the managedObjectContext to read data from CoreData
id delegate = [[UIApplication sharedApplication] delegate];
self.managedObjectContext = [delegate managedObjectContext];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"CarparkInfo" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"code=%@",name]];
NSError *error;
CarparkInfo *cgCarpark;
// THIS IS THE LAST LINE TO BE EXECUTED THE 2ND TIME AROUND. THE APPLICATION DOESN'T THROW AN ERROR BUT DOESN'T GO ON TO UPDATE THE CARPARK OBJECT ON THE LINE AFTER
cgCarpark = [[self.managedObjectContext executeFetchRequest:fetchRequest error:&error] lastObject];
cgCarpark.availableSpaces = spaces;
error = nil;
if (![self.managedObjectContext save:&error]) {
//Handle any error with the saving of the context
}
}
我在使用托管对象上下文的方式上做错了吗?
提前感谢您的帮助