ios - 后台线程上的核心数据获取请求仅适用于首次获取
<p><p>我正在使用 NSOperationQueue 和 NSInvocationOperation 来调用我的 UIViewController 上的一个方法,然后该方法调用另一个类中的一个方法,该方法进而解析来自 Web 的 XML 文件并更新一些核心数据托管对象。</p>
<p>当我第一次运行应用程序时,此过程有效,但是当我第二次调用该方法时(再次显示 UIViewController 时),它不会执行 XML 解析器类中的 executeFetchRequest 语句之后的任何行。这是我用来执行的代码:</p>
<p>我有一个 UITableViewController,它在加载时从我的核心数据存储中获取 parking 场的所有静态信息:</p>
<pre><code>- (void)viewDidLoad
{
NSLog(@"viewDidLoad");
;
southeastCarparks = [ init];
southwestCarparks = [ init];
northeastCarparks = [ init];
northwestCarparks = [ init];
carparkLocations = [ initWithObjects:southeastCarparks, southwestCarparks, northeastCarparks, northwestCarparks, nil];
NSFetchRequest *fetchRequest = [ init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"CarparkInfo" inManagedObjectContext:self.managedObjectContext];
;
NSError *error;
self.carparkInfos = ;
for (CarparkInfo *carpark in self.carparkInfos){
if (){
;
} else if (){
;
} else if (){
;
} else if (){
;
}
}
[ addObserver:self
selector:@selector(loadXMLData)
name:@"appDidBecomeActive"
object:nil];
}
</code></pre>
<p>然后,当 View 出现时,我调用 loadXML 方法转到 web 并从 xml 文件中获取最新的 parking 位信息</p>
<pre><code>- (void) viewDidAppear:(BOOL)animated
{
;
NSLog(@"viewDidAppear");
}
- (void) loadXMLData {
NSLog(@"loadXMLData");
NSOperationQueue *queue = ;
NSInvocationOperation *operation = [ initWithTarget:self
selector:@selector(loadXMLDataWithOperation)
object:nil];
;
}
- (void) loadXMLDataWithOperation {
xmlParser = [ loadXMLByURL:xmlFileURL];
;
}
</code></pre>
<p>在 XMLParser 类中,我获取传入的 xmlFileURL,从 Web 检索它,解析它,然后尝试更新 Core Data 存储中的可用空间</p>
<pre><code>-(id) loadXMLByURL:(NSString *)urlString
{
_carparks = [ init];
NSURL *url = ;
NSData *data = [ initWithContentsOfURL:url];
parser = [ initWithData:data];
parser.delegate = self;
;
return self;
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if (!){
return;
}
currentCarpark = ;
NSString *name = ;
currentCarpark.name = name;
NSString *spaces = ;
currentCarpark.spaces = spaces;
;
currentCarpark = nil;
NSFetchRequest *fetchRequest = [ init];
// set up the managedObjectContext to read data from CoreData
id delegate = [ delegate];
self.managedObjectContext = ;
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"CarparkInfo" inManagedObjectContext:self.managedObjectContext];
;
];
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 = [ lastObject];
cgCarpark.availableSpaces = spaces;
error = nil;
if (!) {
//Handle any error with the saving of the context
}
}
</code></pre>
<p>我在使用托管对象上下文的方式上做错了吗?</p>
<p>提前感谢您的帮助</p></p>
<br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
<p><p>我认为@Mark_Kryzhanouski 是正确的,您遇到了僵局。可能是因为您在多个线程上访问您的 <code>NSManagedObjectContext</code> 。您需要小心<code>Core data</code> 中的线程。您的 <code>NSOperation</code> 将在后台线程上运行,因此对 <code>NSManagedObjectContext</code> 的调用不会与 <code>viewDidLoad</code> 中的第一次调用在同一线程上。以下是<code>Core Data</code>并发的一些引用资料...</p>
<p> <a href="http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/CoreData/Articles/cdConcurrency.html" rel="noreferrer noopener nofollow">Concurrency with Core Data</a>和 <a href="http://developer.apple.com/library/ios/#releasenotes/DataManagement/RN-CoreData/index.html" rel="noreferrer noopener nofollow">Core Data Release Notes for OS X v10.7 and iOS 5.0</a> </p>
<p>WWDC 2012 视频“Session 214 - Core Data Best Practices”中也有关于该主题的精彩 WWDC 演示。</p></p>
<p style="font-size: 20px;">关于ios - 后台线程上的核心数据获取请求仅适用于首次获取,我们在Stack Overflow上找到一个类似的问题:
<a href="https://stackoverflow.com/questions/15261648/" rel="noreferrer noopener nofollow" style="color: red;">
https://stackoverflow.com/questions/15261648/
</a>
</p>
页:
[1]