はじめに
前に同じインスタンスかどうかを判定したい時にやり方がわからなかったのでメモ
公式ドキュメントからそのまま引用するが下記のように確かめることができる。
class IntegerRef {
let value: Int
init(_ value: Int) {
self.value = value
}
}
let x = IntegerRef(10)
let y = x
print(ObjectIdentifier(x) == ObjectIdentifier(y))
// Prints "true"
print(x === y)
// Prints "true"
let z = IntegerRef(10)
print(ObjectIdentifier(x) == ObjectIdentifier(z))
// Prints "false"
print(x === z)
// Prints "false"
ちなみにObjectIdentifier
とは公式ドキュメントによると
A unique identifier for a class instance or metatype.
つまり
クラスインスタンスまたはメタタイプの一意の識別子。
とのこと
識別子という意味がよくわからなかったので下記のコードで調べてみた
print("ObjectIdentifier(x)",ObjectIdentifier(x))
print("ObjectIdentifier(y)",ObjectIdentifier(y))
print("ObjectIdentifier(z)",ObjectIdentifier(z))
ObjectIdentifier(x) ObjectIdentifier(0x00006000002ca520)
ObjectIdentifier(y) ObjectIdentifier(0x00006000002ca520)
ObjectIdentifier(z) ObjectIdentifier(0x00006000002c1040)
このように同じインスタンスに対しては同じ値が入っていることがわかる
Overviewについて
ドキュメントでは下記のように記述されている
In Swift, only class instances and metatypes have unique identities.
There is no notion of identity for structs, enums, functions, or tuples.
Swiftでは、クラスインスタンスとメタタイプのみが一意のIDを持ちます。
構造体、列挙型、関数、またはタプルに同一性の概念はありません。
たとえば構造体を下記のように作ってみると
struct IntegerRef2 {
let value: Int
init(_ value: Int) {
self.value = value
}
}
let X = IntegerRef2(10)
print("ObjectIdentifier(X)",ObjectIdentifier(X))
下記のようなエラーが出力される
Cannot invoke initializer for type 'ObjectIdentifier' with an argument list of type '(IntegerRef2)'
ドキュメントのイニシャライザをみてみると
init(AnyObject)
Creates an instance that uniquely identifies the given class instance.
init(Any.Type)
Creates an instance that uniquely identifies the given metatype.
となっており引数はAnyObject
といえど
特定のクラスインスタンスを一意に識別するインスタンスを作成する
か
与えられたメタタイプを一意に識別するインスタンスを作成する
イニシャライザしかなく、構造体を入れることはできないんだなぁと改めて思った
使い方
一意なクラスの識別子を使ってどんなことができるのかという例
参考にしたライブラリだと下記の例を見つけた
let id = UInt(bitPattern: ObjectIdentifier({クラスのインスタンスを入れる}))
UInt(bitPattern:)の使い方は下記のように引数にIntを入れたらいいらしい
ドキュメントによるとこの引数は,新しいインスタンスのバイナリ表現のソースとして使用する値をいれてくださいとのこと
init(bitPattern x: Int)
Appleのドキュメントの例だと下記のような感じで続きを書くと
let id1 = UInt(bitPattern: ObjectIdentifier(x))
let id2 = UInt(bitPattern: ObjectIdentifier(y))
let id3 = UInt(bitPattern: ObjectIdentifier(z))
print(id1)
print(id2)
print(id3)
出力結果はこんなかんじ
105553146139456
105553146139456
105553146092352
しかし、入れている値ObjectIdentifier(x)
の型はObjectIdentifier
なのにどうしてInt
の引数にはいるのかはよくわからなかった・・・(わかる方教えてください )
こういうふうにクラスを引数に入れるとそのクラスが一意になる番号を取得する方法があるのだなと学びになった
//////////////1/6(追記)
昨日気が付かなかったのだけど
init(bitPattern x: Int)
これ以外にちゃんと objectID
でイニシャライズする関数が存在していた
あるやんけ
/// Creates an integer that captures the full value of the given object
/// identifier.
public init(bitPattern objectID: ObjectIdentifier)
//////////////