Generic Function

isKnownUniquelyReferenced(_:)

Returns a Boolean value indicating whether the given object is known to have a single strong reference. あるブール値を返して、与えられたオブジェクトが1つだけ強い参照を持つことを知られるかどうかを指し示します。

Declaration 宣言

func isKnownUniquelyReferenced<T>(_ object: inout T) -> Bool where T : AnyObject

Parameters パラメータ

object

An instance of a class. This function does not modify object; the use of inout is an implementation artifact. あるクラスのインスタンス。この関数はobjectを修正しませんinoutの使用は、技巧上の実装です。

Return Value 戻り値

true if object is known to have a single strong reference; otherwise, false. objectが強い参照をただ1つだけ持つものと知られているならばtrue;そうでなければ、false

Discussion 解説

The isKnownUniquelyReferenced(_:) function is useful for implementing the copy-on-write optimization for the deep storage of value types: isKnownUniquelyReferenced(_:)関数は、値型の深い貯蔵に対してコピーオンライト最適化を実装するのに便利です:


mutating func update(withValue value: T) {
    if !isKnownUniquelyReferenced(&myStorage) {
        myStorage = self.copiedStorage()
    }
    myStorage.update(withValue: value)
}

Use care when calling isKnownUniquelyReferenced(_:) from within a Boolean expression. In debug builds, an instance in the left-hand side of a && or || expression may still be referenced when evaluating the right-hand side, inflating the instance’s reference count. For example, this version of the update(withValue) method will re-copy myStorage on every call: isKnownUniquelyReferenced(_:)をブール式の内部から呼び出すとき注意を払ってください。デバッグビルドにおいて、&&または||式の左手側でのインスタンスは、右手側を評価している時に依然として参照されるかもしれません、インスタンスのもつ参照カウントを上昇させながら。例えば、このバージョンのupdate(withValue)メソッドはmyStorageを全ての呼び出しで再コピーします:


// Copies too frequently:
mutating func badUpdate(withValue value: T) {
    if myStorage.shouldCopy || !isKnownUniquelyReferenced(&myStorage) {
        myStorage = self.copiedStorage()
    }
    myStorage.update(withValue: value)
}

To avoid this behavior, swap the call isKnownUniquelyReferenced(_:) to the left-hand side or store the result of the first expression in a local constant: この挙動を防ぐために、左手側への呼び出しisKnownUniquelyReferenced(_:)を交換するか、最初の式の結果をローカル定数の中に格納してください。


mutating func goodUpdate(withValue value: T) {
    let shouldCopy = myStorage.shouldCopy
    if shouldCopy || !isKnownUniquelyReferenced(&myStorage) {
        myStorage = self.copiedStorage()
    }
    myStorage.update(withValue: value)
}

isKnownUniquelyReferenced(_:) checks only for strong references to the given object—if object has additional weak or unowned references, the result may still be true. Because weak and unowned references cannot be the only reference to an object, passing a weak or unowned reference as object always results in false. isKnownUniquelyReferenced(_:)は与えられたオブジェクトに対する強い参照に対してのみ確認します — objectがさらに弱いまたは非所有参照を持つ場合、結果は依然としてtrueです。弱いおよび非所有の参照は、あるオブジェクトに対する唯一の参照ではありえないので、弱いまたは非所有参照をobjectとして渡すことは常にfalseという結果になります。

If the instance passed as object is being accessed by multiple threads simultaneously, this function may still return true. Therefore, you must only call this function from mutating methods with appropriate thread synchronization. That will ensure that isKnownUniquelyReferenced(_:) only returns true when there is really one accessor, or when there is a race condition, which is already undefined behavior. objectとして渡されるインスタンスが複数のスレッドによって同時にアクセスされる場合、この関数は依然としてtrueを返します。したがって、あなたはこの関数を変更メソッドから適切なスレッド同期で呼ぶだけにしてください。それはisKnownUniquelyReferenced(_:)が本当に1つのアクセッサしかない時に、またはすでに未定義挙動であるところの競合状態の時にtrueを返すだけであるのを確実にします。

See Also 参照

Uniqueness Checking 特有性の検査