文書   >   Swift   >   Swift 標準ライブラリ  >   手動でメモリ管理   >   MemoryLayout   >   offset(of:)
型メソッド
offset(of:)
与えられたインスタンスの連続したメモリの足跡を返します。
宣言
パラメータ
key | 型 T の値を介してアクセスできる記憶領域を参照するキーパス。 |
戻り値
型 T の値へのポインタから key によって参照される記憶領域へのポインタへのバイト単位のオフセット、または key によって参照される記憶領域にそのようなオフセットが利用できない場合は nil。値が nil の場合、key が計算されて、オブザーバーを持っている、再抽象化が必要である、または記憶領域が他のプロパティとオーバーラップしている可能性があります。
議論
このメソッドを使用して、型 T のポインタに追加できる距離をバイト単位で検索し、key が参照するプロパティへのポインタを取得できます。オフセットは、与えられた key が T のメモリ内表現内のインラインで直接アドレス可能な記憶領域を参照する場合にのみ使用可能です。
このメソッドの戻り値が nil でない場合、キーパスまたはオフセットポインタによる値へのアクセスは同等です。たとえば、型 T の変数 root、WritableKeyPath<T、U> 型のキーパス key、および型 U の値の場合:
// Mutation through the key path root[keyPath: key] = value // Mutation through the offset pointer withUnsafeMutableBytes(of: &root) { bytes in let offset = MemoryLayout<T>.offset(of: key)! let rawPointerToValue = bytes.baseAddress! + offset let pointerToValue = rawPointerToValue.assumingMemoryBound(to: U.self) pointerToValue.pointee = value }
プロパティは、値を抽出または設定するために追加の作業が必要ない、保管されたプロパティである場合、インラインで直接アドレス指定可能な記憶領域を持ちます。プロパティーは、didSet または willSet アクセサーをトリガーする場合、ブリッジングやクロージャの再抽象化などの表現の変更を実行する場合、またはパックされたビットフィールドのように重複する記憶領域から値をマスクする場合、直接アクセスできません。さらに、クラスインスタンスプロパティは常に行外に保管されるため、offset(of:) を使用してそれらの位置にアクセスすることはできません。
たとえば、ここで定義されている ProductCategory 型では、\.updateCounter、\.identifier、および \.identifier.name のみがインラインの直接アドレス可能な記憶領域を持つプロパティを参照します。
struct ProductCategory { struct Identifier { var name: String // addressable } var identifier: Identifier // addressable var updateCounter: Int // addressable var products: [Product] { // not addressable: didSet handler didSet { updateCounter += 1 } } var productCount: Int { // not addressable: computed property return products.count } }
ライブラリからインポートされた型で offset(of:) を使用する場合、ライブラリの将来のバージョンが同じ動作をすると仮定しないでください。プロパティが保管されたプロパティから計算されたプロパティに変換される場合、offset(of:) の結果は nil に変わります。他のコンテキストではこの種の変換は中断されませんが、offset(of:) の結果が強制的に開封されると、実行時エラーが発生します。
トップへ
トップへ
トップへ
トップへ
トップへ