【发布时间】:2014-03-05 16:25:37
【问题描述】:
我在使用 AFNetworking 2.0 和 MagicalRecord 的应用时遇到问题。此应用从播客网站中的一个小 JSON API 下载数据,并将每个播客剧集存储在播客实体中。
此 Podcast 实体有另一个名为 PodcastDownload 的实体,用于在播客下载时保存信息(下载状态和进度)。在这个 PodcastDownload 实体中,我使用 KVO 来更新此信息,观察 NSProgress 对象和来自 NSURLSessionDownloadTask 的状态。这很好用。
但是当我尝试在名为 PodcastManager 的单例实例中使用此方法在数据上下文中保存下载状态时遇到问题:
- (void)saveContext{
[[NSManagedObjectContext defaultContext] saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
if (success) {
NSLog(@"Save OK");
} else if(error) {
NSLog(@"Error %@", error.description);
}
}];
}
当我调用此方法时,我在 AFNetworking 的 AFURLSessionManager 中收到此 EXC_BAD_ACCESS 错误,但根据我的日志,保存似乎运行正常:
Context BACKGROUND SAVING (ROOT) is about to save. Obtaining permanent IDs for new 1 inserted objects
我不知道是什么导致了这个错误。我也尝试使用 MagicalRecord 方法 saveWithBlock 但我得到了相同的结果。
这是我在 PodcastDownload 中的 KVO Observer 的源代码:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (context == PodcastDownloadContext) {
if ([object isKindOfClass:[NSURLSessionDownloadTask class]]) {
NSURLSessionDownloadTask *task = (NSURLSessionDownloadTask *) object;
if (task.state == NSURLSessionTaskStateRunning) {
[self setStatus:PodcastDownloadRunning];
[[PodcastManager sharedManager] saveContext];
}
if (task.state == NSURLSessionTaskStateSuspended) {
[self setStatus:PodcastDownloadSuspended];
[[PodcastManager sharedManager] saveContext];
}
if (task.state == NSURLSessionTaskStateCanceling) {
[self setStatus:PodcastDownloadCanceling];
self.downloadTask = nil;
self.data = nil;
self.progress = 0;
[[PodcastManager sharedManager] saveContext];
}
if (task.state == NSURLSessionTaskStateCompleted) {
if (self.status == PodcastDownloadCanceling) {
[self setStatus:PodcastDownloadNotSet];
} else {
[self setStatus:PodcastDownloadCompleted];
self.downloadTask = nil;
self.data = nil;
self.progress = 0;
[[PodcastManager sharedManager] saveContext];
}
@try {
[object removeObserver:self forKeyPath:NSStringFromSelector(@selector(state)) context:PodcastDownloadContext];
[object removeObserver:self forKeyPath:NSStringFromSelector(@selector(fractionCompleted)) context:PodcastDownloadContext];
}
@catch (NSException * __unused exception) {}
}
}
}
}
非常感谢
【问题讨论】:
-
这可能与保存操作完全没有关系。在分配给它的各种属性之前,您是否检查过以确保您的 self.downloadprogress 对象已正确初始化?
-
是的。事实上,如果我删除保存操作,我的 PodcastDownload 对象中的属性会正确更新。请注意,在 AFURLSessionManager 中出现 EXC_BAD_ACCESS 错误。我编辑了我的问题,添加了这个,对不起,我的错。
-
您的 saveContext 方法对我来说似乎是正确的。我希望我能提供进一步的帮助,但也许其他人会提出建议。我会仔细检查单例代码以确保单例已正确初始化并检查变量以确保它们都已正确初始化。 EXC_BAD_ACCESS 通常在尝试使用未正确初始化的对象或将错误类型作为参数发送给其他方法(即发送 int 到期望指针的对象)时抛出。这些始终是我诊断该异常的前两个地方。
标签: ios iphone objective-c magicalrecord afnetworking-2