Swift在"无主(安全)"和"无主(不安全)"之间有什么区别?

oro*_*ome 26 memory-management automatic-ref-counting swift

苹果斯威夫特编程语言指南中提到的捕捉符 unowned(safe)unowned(unsafe),除了weakunowned.

我(想我)明白之间的差别weakunowned; 但unowned(safe)和之间有什么区别unowned(unsafe)?指南没有说.


请:不要仅仅依赖于描述Objective-C等价物.

Jef*_*mas 32

据我了解,虽然我找不到Apple的权威来源,但unowned可以分为两种口味,safe而且unsafe.

unownedunowned(safe):它是一个特殊包装的引用,它会在引用dealloced实例时抛出异常.

特殊情况是unowned(unsafe):它是Swift等同于Objective C @property (assign)__unsafe_unretained.它不应该在Swift程序中使用,因为它的目的是桥接用Objective C编写的代码.

因此,您将unowned(unsafe)在查看Cocoa类的导入包装时看到,但除非必须,否则不要使用它,并且您将知道何时需要.


更新

__unsafe_unretained是一个简单的指针.它不知道被指向的实例何时被释放,因此当它被解除引用时,底层内存可能是垃圾.

如果您有使用dealloced __unsafe_unretained变量的缺陷,您将看到不稳定的行为.有时候足够的内存位置的足够好,所以该代码将运行,有时它会已部分被覆盖,所以你会得到非常奇怪的崩溃,有时该内存位置将包含一个新的对象,所以你会得到无法识别的选择例外.

转换到ARC发行说明

__unsafe_unretained指定一个引用,该引用不会使引用的对象保持活动状态,并且在没有对该对象的强引用时不会设置为nil.如果它引用的对象被释放,则指针悬空.

  • 因此,总而言之,与`strong`引用不同,`weak`和所有`unowned`s'对引用计数没有贡献.因此,一旦所有`strong`引用都消失了,引用的实例将被释放(当只有`weak`和`unowned`引用它时); `weak`引用将被设置为`nil`(它们因此具有可选类型),而`unowned`将不会.但是,对未释放的实例的"无主(安全)"引用将在访问时抛出可预测的异常,而"无主(不安全)"引用将像一个简单的旧指针,并且行为不可预测.对? (14认同)
  • @raxacoricofallapatorius,不,那不对."无主"和"无主(安全)"会引起参考计数成本 - 即安全成本,以及为什么甚至可以使"无主(不安全)"可用? - 而且它目前比常规强参考计数成本更差,因为ARC不是不优化它.不会抛出异常; 他们在误用时陷阱,永久停止程序. (4认同)

Val*_*gin 19

以下是Apple Developer Forums的引用:

unownedvs unowned(safe)vsunowned(unsafe)

unowned(safe)是一个非拥有的引用,在访问时声明对象仍然存在.它有点像一个弱的可选引用,x!每次访问它时都会隐式解包. unowned(unsafe)就像__unsafe_unretained在ARC 中一样,它是一个非拥有的引用,但没有运行时检查对象在访问时仍然存活,因此悬空引用将进入垃圾内存. unowned始终是unowned(safe)当前的同义词,但目的是unowned(unsafe)-Ofast 禁用运行时检查时,它将在构建中进行优化.


Che*_* OT 6

变量在已使用属性解除分配时被访问:

无主的

  • 程序知道它无效,并立即崩溃。
  • 行为已定义。

无主(不安全)

  • 程序什么都不知道。
  • 它可能会立即崩溃。
  • 它可能会访问未知的内存地址并具有奇怪的状态,直到它在意外位置死亡。
  • 行为未定义。生活越来越艰难。


Aab*_*aza 5

一个简单的定义。这会消除混乱。

-- 无主属性:如果在释放其引用的实例后尝试访问无主引用,则程序将崩溃。

-- unowned(Unsafe) 属性:如果在它所引用的实例被释放后尝试访问一个不安全的无主引用,您的程序将尝试访问该实例曾经所在的内存位置,这是一个不安全的操作。(不保证这是否会执行或崩溃)