我有一个经典的主细节视图应用程序。在详细视图中,我添加了pull to refresh功能来刷新网络数据。即使我无法复制,我也会收到与此刷新功能相关的崩溃报告。我试图限制我的连接,刷新很多次,在视图控制器之间来回,仍然无法重现它。我想我应该在这里使用弱者或无主人,但我不确定选择哪一个。 User
是我从Master View传递的Core Data对象。我的崩溃报告指示在对用户执行写操作期间,程序崩溃。 Crashlytics报告User.detail.count为0,这似乎表明User.detail已被释放?如果你能帮我解决这个问题,我感激不尽。
class User:NSManagedObject {
@NSManaged var detail: NSOrderedSet
}
class UserDetail:NSManagedObject {
@NSManaged var message:String?
}
class APIService {
func getData(date:NSDate?,success: (User) -> Void, failure: (NSHTTPURLResponse?, AnyObject?, ErrorType) -> Void) {
}
}
class ViewController {
var myUser:User!
typealias UserCompletion = (error: ErrorType?) -> Void
func deleteDetails() {
}
func updateDetails() {
}
func refreshList(completion: UserCompletion) {
let downloadGroup = dispatch_group_create()
var storedError: ErrorType?
let service = APIService()
dispatch_group_enter(downloadGroup)
service.getData(nil,
success: { user in
var isitNew = false
//first check if the amount of details changed.
if user.detail.count == self.myUser.detail.count {
let oldDetail = self.myUser.detail.lastObject as! UserDetail
let newDetail = user.detail.lastObject as! UserDetail
if oldDetail.message != newDetail.message {
isitNew = true
}
}
if isitNew || (user.detail.count > 0 && user.detail.count != self.myUser.detail.count) { //something is changed
//Following log function logs detail count as 0 "Something is new count: 0"
//CLSLogv("Something is new count: %d", getVaList([self.myUser.detail.count]))
//Crash after this log
// delete old details and update
self.deleteDetails()
self.updateDetails()
}
dispatch_group_leave(downloadGroup)
},
failure: { response, document, error in
storedError = error
dispatch_group_leave(downloadGroup)
})
// Exit from group
dispatch_group_notify(downloadGroup, dispatch_get_main_queue()) { // 2
completion(error: storedError)
}
}
}
答案 0 :(得分:0)
修改强>
哦,我觉得我误读了你的帖子(和我最初回答的问题一样)。在闭包中使用[弱自我]来获得弱引用:
success: { [weak self] user in
var isitNew = false
//first check if the amount of details changed.
if user.detail.count == self?.myUser.detail.count {
let oldDetail = self?.myUser.detail.lastObject as! UserDetail
let newDetail = user.detail.lastObject as! UserDetail
if oldDetail.message != newDetail.message {
isitNew = true
}
}
if isitNew || (user.detail.count > 0 && user.detail.count != self?.myUser.detail.count) { //something is changed
//Following log function logs detail count as 0 "Something is new count: 0"
//CLSLogv("Something is new count: %d", getVaList([self?.myUser.detail.count]))
//Crash after this log
// delete old details and update
self?.deleteDetails()
self?.updateDetails()
}
dispatch_group_leave(downloadGroup)
}
原始回复 (暂时留下这个 - 可能仍然是你的崩溃的原因)
我认为您的问题可能是详细视图控制器保留对NSManagedObject的引用,其基础数据通过网络调用从数据存储中删除(similar issue)
一个建议是不要在细节中保留对NSManagedObject本身的引用,而是保留与之比较的关键属性。
另一个想法是让你的getData返回" isitNew"值。该函数将知道是否创建了新的核心数据条目。
但我保持最佳解决方案(在我看来)。您可以使用NSFetchedResultsController来检测更改。将您的详细信息视图设置为NSFetchedResultsControllerDelegate。 Apple文档实际上包含了如何执行此操作的一个很好的示例。
最后一个解决方案的优点是你可以摆脱闭包,并将数据与数据的任何变化分离。当您需要扩展应用程序并引入其他更改源时,这可能有用。此来源可能不知道您的详细视图控制器,也可能不知道它。