gpt4 book ai didi

ios - UInavigationController 中使用异步代码的弱无主用法

转载 作者:行者123 更新时间:2023-11-28 08:50:15 25 4
gpt4 key购买 nike

我有一个经典的主细节 View 应用程序。在详细 View 中,我添加了拉动刷新功能以从网络刷新数据。即使我无法在我这边进行复制,我也会收到与此刷新功能相关的崩溃报告。我试图限制我的连接,刷新了很多次,在 View Controller 之间来回切换,仍然无法重现它。我想我应该在这里使用 weak 或 unowned self 但我不确定选择哪一个。 User 是我从主视图传递的核心数据对象。我的崩溃报告表明在对用户进行写操作期间,程序崩溃了。 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)
}
}
}

最佳答案

编辑

该死的 - 我想我有点误读了您的帖子(遇到了与我最初回答的问题相同的问题)。在闭包中使用 [weak self] 来获取弱引用:

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)

}

原始回复(暂时留下这个 - 可能仍然是你崩溃的原因)

我认为您的问题可能是详细 View Controller 正在保留对 NSManagedObject 的引用,其基础数据已通过网络调用(similar issue)从数据存储中删除

一个建议是不要在细节上保留对 NSManagedObject 本身的引用,而是保留您正在比较的关键属性。

另一个想法是让您的 getData 返回“isitNew”值。该函数会知道是否创建了新的核心数据条目。

但我会保留(在我看来)最好的解决方案。您可以使用 NSFetchedResultsController检测变化。将您的详细 View 设置为 NSFetchedResultsControllerDelegate .苹果文档实际上包含了一个很好的例子来说明如何做到这一点。

最后一个解决方案的优点是您可以摆脱闭包并将细节与数据的任何更改分离开来。有一天,当您需要扩展应用程序并引入另一个更改源时,这可能会很有用。此来源可能不知道您的详细 View Controller ,并且可能也不应该知道。

关于ios - UInavigationController 中使用异步代码的弱无主用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34433249/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com