在WWDC 2014会议403 中级Swift和成绩单中,有以下幻灯片

在这种情况下,发言人说,如果我们不在[unowned self]那里使用,那将是内存泄漏.这是否意味着我们应该始终使用[unowned self]内部封闭?
在Swift Weather应用程序的ViewController.swift的第64行,我不使用[unowned self].但我通过使用一些@IBOutlet像self.temperature和更新UI self.loadingIndicator.它可能没问题,因为@IBOutlet我所定义的都是weak.但为了安全起见,我们应该一直使用[unowned self]吗?
class TempNotifier {
var onChange: (Int) -> Void = {_ in }
var currentTemp = 72
init() {
onChange = { [unowned self] temp in
self.currentTemp = temp
}
}
}
Run Code Online (Sandbox Code Playgroud) 我是Obj-C的新手,所以我的第一个问题是:
之间有什么区别strong,并weak在@property对象的指针的声明?
还有什么nonatomic意思呢?
我理解的使用和肤浅的差异weak,并unowned在斯威夫特:
我见过的最简单的例子是,如果有a Dog和a Bone,则Bone可能有弱引用Dog(反之亦然)因为每个可以彼此独立存在.
在另一方面,在的情况下Human和Heart,则Heart可能有一个unowned人类的参考,因为一旦Human变成......"引用",将Heart不能再合理地进行访问.那和经典的例子一起Customer和CreditCard.
所以这不是问题的重复.
我的问题是,有两个这样相似的概念有什么意义?内部差异是什么,需要两个关键字,看起来基本上99%相同的东西?问题是为什么存在差异,而不是存在差异.
鉴于我们可以像这样设置一个变量:weak var customer: Customer!,unowned变量不可选的优点是一个有争议的问题.
我可以看到使用vs隐式展开变量via 的唯一实际优点是我们可以通过引用使引用保持不变.
unownedweak!unownedlet
......也许编译器可以为此做出更有效的优化.
这是真的,还是在幕后发生了其他事情,为保留两个关键词提供了令人信服的论据(尽管略有区别 - 基于Stack Overflow流量 - 显然让新的和经验丰富的开发人员感到困惑).
我最感兴趣的是听过那些使用过Swift编译器(或其他编译器)的人.
经过一些研究,我发现我的应用程序使用了太多的能量,因为UIView整个应用程序中有几个动画,我在完成块中捕获了相关的动画UIViewController,而没有对其进行弱引用。
所以实际上,我改变了这一点:
func animate() {
UIView.animate(withDuration: 0.3, animations: {
self.label.alpha = 0.5
}) { _ in
self.animate()
}
}
Run Code Online (Sandbox Code Playgroud)
进入这个:
func animate() {
UIView.animate(withDuration: 0.3, animations: {
self.label.alpha = 0.5
}) { [weak self] _ in
self?.animate()
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我想知道我是否需要对animation块(self.label.alpha = 0.5那个)做同样的事情?
感谢您的帮助
我正在用 Swift 构建一个物理引擎。在对引擎进行了一些最近的添加并运行了基准测试之后,我注意到性能大大降低了。例如,在下面的屏幕截图中,您可以看到 FPS 如何从 60 FPS 下降到 3 FPS(FPS 位于右下角)。最终,我将问题归结为一行代码:
final class Shape {
...
weak var body: Body! // This guy
...
}
Run Code Online (Sandbox Code Playgroud)
在我添加的某个时候,我添加了一个从Shape类到Body类的弱引用。这是为了防止强引用循环,因为Body也有对Shape.
不幸的是,弱引用似乎有很大的开销(我想将它清零的额外步骤)。我决定通过构建下面物理引擎的大规模简化版本并对不同的参考类型进行基准测试来进一步研究这一点。
import Foundation
final class Body {
let shape: Shape
var position = CGPoint()
init(shape: Shape) {
self.shape = shape
shape.body = self
}
}
final class Shape {
weak var body: Body! //****** This line is the problem ******
var vertices: [CGPoint] = []
init() …Run Code Online (Sandbox Code Playgroud) performance weak-references strong-references swift unowned-references
弱和无主引用用于防止在两个对象各自保持对另一个的引用的情况下的保留周期.我得到弱者的使用,但我没有得到无主的使用.以下是Apple的示例,其中两个对象之一应使用无主参考:
class Customer {
let name: String
var card: CreditCard?
init(name: String) { self.name = name }
}
class CreditCard {
let number: UInt64
unowned let customer: Customer
init(number: UInt64, customer: Customer) {
self.number = number
self.customer = customer
}
}
Run Code Online (Sandbox Code Playgroud)
这个想法是没有客户就不能存在信用卡.因此,信用卡可以省去使用弱引用所需的可选展开,并且可以使用无主参考.嗯...那么为什么不使用强大的参考?如果对客户的所有其他引用都消失了(这不应该发生?)那么信用卡使用自己的引用会导致崩溃; 而使用强引用会导致内存泄漏.咦?两种邪恶之间的选择?更好地崩溃,因为在开发和测试期间更容易被注意到?
请帮忙解决一下.谢谢.
有没有办法检查unowned(safe)Swift引用的"可用性"?所以,我正在寻找一个假设的函数isReferenceAccessible,如下例所示:
func someMethod() {
someAsyncOperation(parameters) { [unowned(safe) self] in
guard isReferenceAccessible(self) else {
return
}
self.someAnotherMethod()
}
}
Run Code Online (Sandbox Code Playgroud)
免责声明:这个问题与weak参考文献无关!我知道如何strong,unowned以及weak引用的工作.而且我不想使用weak引用(因为它可能很慢,而且可变).我知道unowned(safe)即使已经deinited在我们尝试访问它时,仍然会分配引用.我知道编译器可以执行此检查,并在应用程序崩溃之前实际检查它.
因此,我相信它可以是非常强大且执行良好的技术/范例,可以打破现代Swift中的参考周期.
而且,我相信它可以是一个很棒的语言功能!例如,让我们假设我们已经调用了修饰符shared_ownership,它的工作思路如上所述:
method(parameters) { [shared_ownership self] in
self.someAnotherMethod()
}
Run Code Online (Sandbox Code Playgroud)
......实现如下:
method(parameters) { [unowned(safe) self] in
guard isReferenceAccessible(self) else {
return
}
self.someAnotherMethod()
}
Run Code Online (Sandbox Code Playgroud)
......副作用(没有weak相关的复杂性和性能惩罚)相当于:
method(parameters) { [weak self] in
guard let strongSelf = self else {
return …Run Code Online (Sandbox Code Playgroud) 在Swift中,我们有正常的默认输入
我们打字很弱
我们打字无人打字
(所以:通过推论:你可以使用"无主"的唯一一次是,如果你"绝对知道"该对象将永远不会变为零.)
现在:
在我看来,以下句子,
绝对是真的......
绝对地,我的意思是,真的,真的,绝对,直到最深刻的哲学关注真实......
因而是逻辑推论:
{旁白 - 我能想到的唯一其他差异在于自我记录的意义.如果我使用无主,它会让我的开发人员知道某些事情; 让我们暂时搁置这个问题.)
所以我的问题很简单,非常准确,非常具体:大胆的句子高于"真实"(在"完全,非常,非常,真实"的真实意义上).
每当我做异步网络请求时,可能是在请求到达时self已经是nil(例如,ViewController已被解除).
为了防止这种情况,我通常将自我视为弱者:
future.onSuccess(context: Queue.main.context, callback: { [weak self] result in
if let strongSelf = self {
// Do some stuff with self, which is now guaranteed to be not nil
// strongSelf.someMethod()
}
})
Run Code Online (Sandbox Code Playgroud)
或者我可以将自己视为无主:
future.onSuccess(context: Queue.main.context, callback: { [unowned self] result in
// Do some stuff with self
// self.someMethod()
})
Run Code Online (Sandbox Code Playgroud)
我不关心请求返回,因为当请求在ViewController已被解除的时间点返回时,我没有从请求中显示任何内容.所以我不想让关闭时自己"活着".
我现在的问题是 - 在这种情况下是否足以将自己视为无主?或者我必须一直做[弱自我]的零检查?如果在请求到达并且self已经为零时无主捕获的情况下会发生什么 - 闭包是否仍然存在且将执行并且将在访问nil时触发运行时错误?或者封闭也会与自己一起解除分配,请求会遇到"空白"?
或者在这种情况下我可以忘记弱者和无人物,因为当自我取消分配时,闭包也将被解除分配,因此在请求到达时没有访问nil的危险吗?
PS:我知道关于这个话题已经有很多问题 - 答案但是在我不关心异步到达的情况下我找不到答案.
如果你的狗有一个弱的参考骨,这意味着狗在这种情况下是参考的"拥有者",它使用骨骼,但骨骼可以不存在,狗仍然可以运作(因为参考to bone是可选的).
然而,对于"无主",似乎关键字"无主"不是在所有者的引用声明中使用,而是在另一个对象中使用.例如,Bone对其狗的引用被标记为"无主".
无主是不安全的.如果所有者在程序中的某个时刻不存在,它可能会崩溃,并且它不能是可选的.为什么人们会使用无主而不是弱引用?
为什么不用弱?从我的理解来看,这只是与大声失败和失败的失败有关.在无主的情况下,如果骨头没有狗,应用程序将始终崩溃,而如果我们使用弱,您将最终得到一个仍然存在的骨骼,带有"幽灵"狗.
在Swift中,可以选择使用unowned或weak.为何unowned可以使用weak?似乎两者几乎相同,weak更安全.
ARC是否保留对对象的无主引用计数?
那么,如果某个对象的强引用计数达到0并且该对象的未拥有引用计数> 0,则该对象将被取消初始化但未取消分配?并且只有当强大且无主的引用计数达到0时,它才会被取消分配吗?
我在一篇有关Medium的文章中阅读过),但是我不确定它是正确的。
automatic-ref-counting strong-references swift unowned-references
我正在努力了解何时需要注意强参考周期可能造成的内存泄漏.从我从swift文档中收集的内容来看,self在同一实例中声明为实例属性的闭包中使用引用将导致强引用循环,除非我声明了捕获列表,例如:
class A {
var a: String
lazy var aClosure: () -> () = { [unowned self] in
println(self.a)
}
init(a: String) {
self.a = a
}
}
Run Code Online (Sandbox Code Playgroud)
现在,没有存储为实例属性的闭包或作为其他类的实例属性存储的闭包会发生什么?在这些情况下,我是否还需要担心强大的参考周期?
swift ×12
ios ×4
closures ×2
reference ×2
animation ×1
asynchronous ×1
memory-leaks ×1
objective-c ×1
performance ×1
uiview ×1