當前位置: 首頁>>編程示例 >>用法及示例精選 >>正文


Swift MemoryLayout offset(of:)用法及代碼示例

類型方法

offset(of:)

返回類型的內存表示中內聯存儲屬性的偏移量。

聲明

static func offset(of key: PartialKeyPath<T>) -> Int?

返回值

從指向類型為 T 的值的指針到指向由 key 引用的存儲的指針的偏移量(以字節為單位),如果沒有這樣的偏移量可用於由 key 引用的存儲,則為 nil。如果值為 nil ,則可能是因為 key 已計算、具有觀察者、需要重新抽象或與其他屬性重疊存儲。

參數

key

引用存儲的鍵路徑,可以通過 T 類型的值訪問。

詳述

您可以使用此方法查找可以添加到類型 T 的指針的字節距離,以獲取指向 key 引用的屬性的指針。僅當給定鍵引用 T 的內存表示中的內聯、直接可尋址存儲時,偏移量才可用。

如果此方法的返回值不是 nil ,則通過鍵路徑或偏移指針訪問該值是等效的。例如,對於類型為 T 的變量 root 、類型為 WritableKeyPath<T, U> 的鍵路徑 key 和類型為 Uvalue


// 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
}

當一個屬性是一個存儲屬性,不需要額外的工作來提取或設置值時,它就具有內聯、可直接尋址的存儲。如果屬性觸發任何 didSetwillSet 訪問器、執行任何表示更改(例如橋接或閉包重新抽象)或將值從重疊存儲中屏蔽(如打包位域),則無法直接訪問這些屬性。此外,由於類實例屬性始終存儲 out-of-line,因此無法使用 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:) 的結果是force-unwrapped,則會觸發運行時錯誤。

可用版本

iOS 8.0+, iPadOS 8.0+, macOS 10.10+, Mac Catalyst 13.0+, tvOS 9.0+, watchOS 2.0+

相關用法


注:本文由純淨天空篩選整理自apple.com大神的英文原創作品 MemoryLayout offset(of:)。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。