- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 viewController
保持对其 viewModel
的(强)引用
lazy private var viewModel: ListViewModel = {
return ListViewModel()
}()
override func viewDidLoad() {
super.viewDidLoad()
initViewModel()
}
private func initViewModel() {
viewModel.onModelChange = { [weak self] () in
DispatchQueue.main.async {
self?.tableView.reloadData()
}
}
viewModel.fetchData()
}
Apple 的 Swift 文档日:
A strong reference cycle can also occur if you assign a closure to a property of a class instance, and the body of that closure captures the instance.
这个 viewController
包含一个 viewController
,它包含一个捕获 viewController
的闭包,所以我知道可能会发生强引用循环。
这些是 viewModel
的属性:
var onModelChange: (() -> Void)?
private var model: [MyModel] = [MyModel]() {
didSet {
self.onModelChange?()
}
}
另一方面,这个 viewController
是 root
一个,所以在应用程序的生命周期中不会被释放。而且我没有明确nilify它的 viewModel
属性。所以:
[weak self]
但是,因为看起来 viewController
及其 viewModel
会同时被释放,我想我应该定义 [unowned self]
来代替?在有疑问的情况下定义 [weak self]
是否有害?假设现在 viewController
被推到 root
之上,因此它可以在应用程序的生命周期中弹出。 viewController
的 fetchData()
方法是这样的:
func fetchData() {
dataSource.getData(completion: { (result, error) -> Void in
if error != nil {
self.model = [MyModel]()
} else {
if let result = result {
self.model = result
} else {
self.model = [MyModel]()
}
}
})
}
其中 dataSource
是一个强大的属性,可以从本地文件(同步任务)或调用服务(异步任务)获取数据。
model
也是一个被观察并调用 viewController
提供的闭包的属性
所以:
dataSource
从本地文件获取数据。如果同时弹出 viewController
会发生什么?在 dataSource
完成之前,viewModel
是否仍然存在?在这种情况下,在闭包中提供 [weak self]
捕获列表是否正确?dataSource
正在执行异步网络调用,而 viewController
同时弹出,将是和以前一样的场景?我的意思是,在 dataSource
完成之前,viewModel
是否仍然存在?编辑: 场景/问题 5
现在我的 viewModel
还请求一个对象 UserSettingsManager
来获取一些其他数据:
func getUserSettings() {
UserSettingsManager.getInfo { (result, error) in
if error == nil {
self.userData = result
}
}
}
}
但是这个 UserSettingsManager
不像 dataSource
那样是 viewModel
的属性,它是一个只提供 static func 的类
。那些 static func
作为 @escaping
传递闭包,所以我猜在这种情况下也可能发生强引用循环,对吗?或者这种情况会不同于以前的情况吗?我在这里需要哪个捕获列表(如果有)?
最佳答案
Question 1: is there actually a risk of a strong reference cycle happening? Should I provide a capture list to the closure anyway?
强引用循环将会发生。问题应该是强引用周期是否重要。在这种情况下可能不会,但无论如何保留弱引用可能是个好主意,以防您将来移动 Controller 。为 future 的安全付出的代价很小。
Question 2: I set the capture list to be [weak self] but, since it seems the viewController and its viewModel would be deallocated same time, I guess I should have defined [unowned self] instead? Does it hurt to define [weak self] in case of doubt?
[unowned self]
表示调用闭包时 self
肯定存在。除非您完全确定是这种情况,否则您应该坚持使用 [weak self]
。我的偏好是始终使用 weak
,因为安全解包不需要太多额外的努力,并且如果您以某种方式错过了可以释放 self
的情况,则可以避免崩溃。如果您在闭包中多次使用 self
,最好将它解包在一个 guard 语句中或将代码移动到一个单独的函数中。
Question 3: in case the dataSource is getting the data from a local file. What happens then if the viewController is pop in the meanwhile? Would the viewModel still be alive until the dataSource finishes? In such case, is it correct to provide the [weak self] capture list in the closure?
在您的示例中,您在闭包中有一个对 self
的强引用,因此您有一个强引用循环,这意味着 ViewController 永远不会被释放。
无论哪种方式,如果您同步获取数据,点击以关闭 View Controller 将无法完成它的工作,直到从文件中获取数据和 block 中的代码完成。这些必须在主线程变得畅通之前完成,并且可以执行关闭 Controller 的代码。
Question 4: in case the dataSource is performing an async network call, and the viewController is pop in the meanwhile, would be the same scenario than before? I mean, would the viewModel be still alive until the dataSource finishes?
如果您将它设为弱引用,并且 dataSource 保留在 Controller 外部,因此它比 Controller 长寿,则在调用闭包时 self
可能为 nil。
关于ios - MVVM - 使用闭包将 ViewModel 与数据源绑定(bind) : capture list needed?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51226881/
我想使用 R 预定义这样的列表 DATA<-list( list(list(),list(),list()), list(list(),list(),list()), list(list(),l
如何将一个列表添加到另一个列表,返回一个列表的列表? foo :: [a] -> [a] -> [[a]] 例如,我想要的结果是: foo [1,2] [3,4] 将是 [[1,2], [3,4]]。
我还没有在这里找到类似问题的解决方案,所以我会寻求你的帮助。 有 2 个列表,其中之一是列表列表: categories = ['APPLE', 'ORANGE', 'BANANA'] test_re
这个问题不同于Converting list of lists / nested lists to list of lists without nesting (这会产生一组非常具体的响应,但无法解决
原始列表转换为 List正好。为什么原始列表的列表不能转换为 List 的列表? { // works List raw = null; List wild = raw; } {
在下面的代码中,get()被调用并将其结果分配给类型为 List> 的变量. get()返回 List>并在类型参数为 T 的实例上调用设置为 ? ,所以它应该适合。 import java.util
原始列表转换为 List正好。为什么原始列表的列表不能转换为 List 的列表? { // works List raw = null; List wild = raw; } {
在insufficiently-polymorphic 作者说: def foo[A](fst: List[A], snd: List[A]): List[A] There are fewer way
我有下面的代码有效。 class ListManipulate(val list: List, val blockCount: Int) { val result: MutableList>
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 5 年前。 Improve this ques
在 scala (2.9) 中转换列表列表的最佳方法是什么? 我有一个 list : List[List[A]] 我想转换成 List[A] 如何递归地实现这一点?或者还有其他更好的办法吗? 最佳答案
我编写了这个函数来确定给定元素是否存储在元组列表的列表中,但目前它只搜索第一个列表。我将如何搜索其余列表? fun findItem (name : command, ((x,y)::firstlis
我创建了一个类名 objectA,它有 4 个变量:约会时间;字符串文本;变量 1,变量 2 我需要创建一个 ObjectA() 列表。然后首先按时间对它们进行分组,其次按 var1,然后按 var2
我有一套说法 char={'J','A'} 和列表的列表 content = [[1,'J', 2], [2, 'K', 3], [2, 'A', 3], [3,'A', 9], [5, 'J', 9
我有以下列表 List >>> titles = new ArrayList >>> ();我想访问它的元素,但我不知道该怎么做.. 该列表有 1 个元素,它又包含 3 个元素,这 3 个元素中的
转换 List[List[Long]] 的最佳方法是什么?到 List[List[Int]]在斯卡拉? 例如,给定以下类型列表 List[List[Long]] val l: List[List[Lo
我有一个来自 Filereader (String) 的 List-List,如何将其转换为 List-List (Double):我必须返回一个包含 line-Array 的第一个 Values 的
我收集了List> 。我需要将其转换为List> 。这是我尝试过的, List> dataOne = GetDataOne(); var dataTwo = dataOne.Select(x => x
这个问题在这里已经有了答案: Cannot convert from List to List> (3 个答案) 关闭 7 年前。 我没有得到这段代码以任何方式编译: List a = new Ar
这个问题在这里已经有了答案: Cannot convert from List to List> (3 个答案) 关闭 7 年前。 我没有得到这段代码以任何方式编译: List a = new Ar
我是一名优秀的程序员,十分优秀!