Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Swiftのas Any / AnyObjectの暗黙的な型変換について

Swiftのas Any / AnyObjectの暗黙的な型変換について

Yu Sugawara

March 18, 2022
Tweet

More Decks by Yu Sugawara

Other Decks in Technology

Transcript

  1. Swiftͷas Any / AnyObjectͷ
    ҉໧తͳܕม׵ʹ͍ͭͯ
    iPhone Dev SapporoษڧձΦϯϥΠϯ Mar, 2022
    1

    View Slide

  2. ੁݪ ༞
    @yusuga_
    2

    View Slide

  3. ໰୊1
    let int: Int = 0
    print(type(of: int)) // Int
    print(type(of: int as AnyObject)) // ԿʹͳΔʁ
    3

    View Slide

  4. ౴͑1
    let int: Int = 0
    print(type(of: int)) // Int
    print(type(of: int as AnyObject)) // __NSCFNumber
    __NSCFNumber
    ≒ NSNumber
    4

    View Slide

  5. ໰୊2
    let string = ""
    print(type(of: string)) // String
    print(type(of: string as AnyObject)) // ԿʹͳΔʁ
    5

    View Slide

  6. ౴͑2
    let string = ""
    print(type(of: string)) // String
    print(type(of: string as AnyObject)) // __NSCFConstantString
    __NSCFConstantString
    ≒ NSString
    6

    View Slide

  7. ͳ͔ͥObjectice-Cܥͷܕʹ
    ม׵͞Ε͍ͯΔͧʂ
    !
    7

    View Slide

  8. ໭͢͜ͱ΋Մೳ
    let int: Int = 0
    type(of: (int as AnyObject) as! Int) // Int
    8

    View Slide

  9. ໰୊3
    struct StructModel {}
    let structModel = StructModel()
    type(of: structModel) // StructModel
    type(of: structModel as AnyObject) // ԿʹͳΔʁ
    9

    View Slide

  10. ౴͑3
    struct StructModel {}
    let structModel = StructModel()
    type(of: structModel) // StructModel
    type(of: structModel as AnyObject) // __SwiftValue
    __SwiftValue
    10

    View Slide

  11. __SwiftValue
    !
    11

    View Slide

  12. ղઆ
    12

    View Slide

  13. SwiftͱObjective-Cͷܕͷ૬ޓม׵
    13

    View Slide

  14. SwiftͱObjective-Cͷܕͷ૬ޓม׵
    • Objective-C and Swift interoperabilityʢ૬ޓӡ༻ੑʣʹΑͬͯɺ
    SwiftͱObjective-CͷܕΛ૬ޓʹม׵͕ߦ͑Δ࢓༷ʹͳ͍ͬͯ
    Δɻ
    13

    View Slide

  15. SwiftͱObjective-Cͷܕͷ૬ޓม׵
    • Objective-C and Swift interoperabilityʢ૬ޓӡ༻ੑʣʹΑͬͯɺ
    SwiftͱObjective-CͷܕΛ૬ޓʹม׵͕ߦ͑Δ࢓༷ʹͳ͍ͬͯ
    Δɻ
    • ม׵͸func _bridgeAnythingToObjectiveC(_ x: T) ->
    AnyObjectͰߦΘΕ͍ͯΔɻ
    13

    View Slide

  16. public func _bridgeAnythingToObjectiveC(_ x: T) -> AnyObject {
    var done = false
    var result: AnyObject!
    let source: Any = x
    if let dynamicSource = _extractDynamicValue(x) {
    result = dynamicSource as AnyObjectɹ// ← ʂʂʂ
    done = true
    }
    14

    View Slide

  17. if !done, let wrapper = source as? _Unwrappable {
    if let value = wrapper._unwrap() {
    result = value as AnyObjectɹ// ← ʂʂʂ
    } else {
    result = _nullPlaceholder
    }
    done = true
    }
    15

    View Slide

  18. if !done {
    if type(of: source) as? AnyClass != nil {
    result = unsafeBitCast(x, to: AnyObject.self) // ↓ʂʂʂ
    } else if let object = _bridgeToObjectiveCUsingProtocolIfPossible(source) {
    result = object
    } else {
    result = _makeSwiftValue(source) // ← ʂʂʂ
    }
    }
    return result
    }
    16

    View Slide

  19. SwiftͱObjective-Cͷܕͷ૬ޓม׵
    17

    View Slide

  20. SwiftͱObjective-Cͷܕͷ૬ޓม׵
    • func _bridgeAnythingToObjectiveC(_ x: T) -> AnyObjectͷத
    ͰObjective-Cͷܕʹม׵΍__SwiftValue΁ͷϥοϓ͕ߦΘΕͯ
    ͍Δɻ
    17

    View Slide

  21. __SwiftValueͱ͸
    // __SwiftValue is an Objective-C class, but we shouldn't interface with it
    // directly as such. Keep the type opaque.
    #if __OBJC__
    @class __SwiftValue;
    #else
    typedef struct __SwiftValue __SwiftValue;
    #endif
    swift/stdlib/public/runtime/SwiftValue.h
    18

    View Slide

  22. __SwiftValueͱ͸
    // __SwiftValue is an Objective-C class, but we shouldn't interface with it
    // directly as such. Keep the type opaque.
    #if __OBJC__
    @class __SwiftValue;
    #else
    typedef struct __SwiftValue __SwiftValue;
    #endif
    swift/stdlib/public/runtime/SwiftValue.h
    • Objective-Cͷclass
    18

    View Slide

  23. ໰୊4
    /* Objective-C */
    @interface ObjCModel : NSObject
    - (NSString *)test:(id)any;
    @end
    @implementation ObjCModel
    - (NSString *)test:(id)any {
    return NSStringFromClass([any class]);
    }
    @end
    19

    View Slide

  24. ໰୊4
    /* Swift */
    class ObjCModel : NSObject {
    func test(_ any: Any!) -> String!
    }
    20

    View Slide

  25. ໰୊4
    let objcModel = ObjCModel()
    type(of: objcModel) // ObjCModel
    objcModel.test(StructModel()) // ԿʹͳΔʁ
    21

    View Slide

  26. ౴͑4
    let objcModel = ObjCModel()
    type(of: objcModel) // ObjCModel
    objcModel.test(StructModel()) // __SwiftValue
    __SwiftValue
    22

    View Slide

  27. Anyͳͷʹʁ
    !
    23

    View Slide

  28. SwiftͰͷas Anyͷڍಈ
    let structModel = StructModel()
    type(of: structModel as Any) // StructModel
    24

    View Slide

  29. SwiftͰͷidܕͷѻ͍
    Objective-C Swift 2 Swift 3
    id AnyObject Any
    NSArray * [AnyObject] [Any]
    NSDictionary * [NSObject: AnyObject] [AnyHashable: Any]
    NSSet * Set Set
    Ҿ༻ݩ: Objective-C id as Swift Any 25

    View Slide

  30. SwiftͰͷidܕͷѻ͍
    Objective-C Swift 2 Swift 3
    id AnyObject Any
    26

    View Slide

  31. SwiftͰͷidܕͷѻ͍
    Objective-C Swift 2 Swift 3
    id AnyObject Any
    • Swift 2Ͱ͸ idܕ͸AnyObjectܕͱͯ͠ѻΘΕ͍ͯͨɻ
    26

    View Slide

  32. SwiftͰͷidܕͷѻ͍
    Objective-C Swift 2 Swift 3
    id AnyObject Any
    • Swift 2Ͱ͸ idܕ͸AnyObjectܕͱͯ͠ѻΘΕ͍ͯͨɻ
    • ͨͩ͠ɺAnyObjectͩͱSwiftͷstruct΍enum͕౉ͤͳ͍ෆ౎߹
    ͕͋ͬͨͨΊɺSwift 3͔ΒAnyܕʹมΘͬͨɻ
    26

    View Slide

  33. SwiftͰͷidܕͷѻ͍
    Objective-C Swift 2 Swift 3
    id AnyObject Any
    27

    View Slide

  34. SwiftͰͷidܕͷѻ͍
    Objective-C Swift 2 Swift 3
    id AnyObject Any
    • ͭ·ΓObjective-CͰ͸ݩʑAnyObjectʢࢀরܕʣ͔͠૝ఆͯ͠
    ͍ͳ͔͕ͬͨɺSwiftͷ஋ܕʢstruct, enumʣΛ౉ͤΔΑ͏ʹ͢
    ΔͨΊʹAnyܕʹมߋ͞Εɺ಺෦ͰରԠ͢Δclassܕʹม׵·ͨ
    ͸ϥοϓ͢Δ͜ͱʹͳͬͨɻ
    27

    View Slide

  35. SwiftͰͷidܕͷѻ͍
    Objective-C Swift 2 Swift 3
    id AnyObject Any
    28

    View Slide

  36. SwiftͰͷidܕͷѻ͍
    Objective-C Swift 2 Swift 3
    id AnyObject Any
    • Objective-CͷAnyܕʹ஋Λ౉͢ͱ as AnyObject ͱಉ͘͡ func
    _bridgeAnythingToObjectiveC(_ x: T) -> AnyObjectʹΑΔܕม
    ׵͕ߦΘΕΔ͜ͱʹͳΔɻ
    28

    View Slide

  37. ࣮ࡍʹૺ۰ͨ͠໰୊
    29

    View Slide

  38. ࣮ࡍʹૺ۰ͨ͠໰୊
    30

    View Slide

  39. ࣮ࡍʹૺ۰ͨ͠໰୊
    • Objective-CͰ࣮૷͞ΕͨAnyܕΛҾ਺ʹ͍࣋ͬͯΔؔ਺ʹର͠
    ͯSwiftͷStructΛ౉ͨ͠ΒɺಉҰͷΠϯελϯεΛ౉͍ͯ͠Δ
    ͷʹObjective-CଆͰ͸ຖճҟͳΔΠϯελϯε͕౉͞Ε͍ͯΔ
    ͱ͍͏൑ఆʹͳͬͯ͠·ͬͨɻ
    30

    View Slide

  40. ࣮ࡍʹૺ۰ͨ͠໰୊
    • Objective-CͰ࣮૷͞ΕͨAnyܕΛҾ਺ʹ͍࣋ͬͯΔؔ਺ʹର͠
    ͯSwiftͷStructΛ౉ͨ͠ΒɺಉҰͷΠϯελϯεΛ౉͍ͯ͠Δ
    ͷʹObjective-CଆͰ͸ຖճҟͳΔΠϯελϯε͕౉͞Ε͍ͯΔ
    ͱ͍͏൑ఆʹͳͬͯ͠·ͬͨɻ
    • ཧ༝͸ɺຖճ৽͍͠__SwiftValueʹϥοϓ͞Εͯ౉͞ΕΔͨ
    Ίɻ
    30

    View Slide

  41. ࣮ࡍʹૺ۰ͨ͠໰୊
    31

    View Slide

  42. ࣮ࡍʹૺ۰ͨ͠໰୊
    • ྫ͑͹ɺؔ਺಺ͰΠϯελϯεͷಉ஋൑ఆΛͨ͠ϩδοΫ͕࣮
    ૷͞Ε͍ͯΔ࣌ʹɺݺͼग़͠ݩ͸ಉҰͷstructΛ౉͍ͯ͠Δͭ΋
    ΓͰ΋ɺؔ਺಺Ͱ͸ҟͳΔΠϯελϯεͱ൑ఆ͞Εͯ͠·͏ͷ
    Ͱҙਤͨ͠ڍಈʹͳΒͳ͘ͳΔɻ
    31

    View Slide

  43. Πϯελϯε͕ҟͳΔ͜ͱΛݕূ
    @frozen struct ObjectIdentifier
    32

    View Slide

  44. Πϯελϯε͕ҟͳΔ͜ͱΛݕূ
    @frozen struct ObjectIdentifier
    • ObjectIdentifierΛ࢖ͬͯɺੜ੒͞ΕͨΠϯελϯεͷҰҙͷID
    Λग़ͯ͠ΈΔͱɺಉҰͷstructͷ͸ͣͳͷʹ as AnyObject ͷ౓
    ʹҧ͏IDʹͳΔ͜ͱ͕֬ೝͰ͖Δɻ
    32

    View Slide

  45. Πϯελϯε͕ҟͳΔ͜ͱΛݕূ
    struct StructModel {}
    let structModel = StructModel()
    Timer.scheduledTimer(
    withTimeInterval: 1,
    repeats: true
    ) { _ in // 1ඵ͝ͱʹΫϩʔδϟ͕࣮ߦ͞ΕΔ
    print("struct", ObjectIdentifier(structModel as AnyObject))
    }
    33

    View Slide

  46. /*
    ग़ྗ͞ΕΔϩά
    struct ObjectIdentifier(0x00006000005749c0)
    struct ObjectIdentifier(0x000060000055ef80)
    struct ObjectIdentifier(0x00006000005557c0)
    struct ObjectIdentifier(0x000060000055dba0)
    struct ObjectIdentifier(0x000060000055ef80)
    struct ObjectIdentifier(0x00006000005557c0)
    */
    34

    View Slide

  47. /*
    ग़ྗ͞ΕΔϩά
    struct ObjectIdentifier(0x00006000005749c0)
    struct ObjectIdentifier(0x000060000055ef80)
    struct ObjectIdentifier(0x00006000005557c0) // ಉ͡IDʂʂʂ
    struct ObjectIdentifier(0x000060000055dba0)
    struct ObjectIdentifier(0x000060000055ef80)
    struct ObjectIdentifier(0x00006000005557c0) // ಉ͡IDʂʂʂ
    */
    35

    View Slide

  48. ObjectIdentifier͸ɺղ์͞ΕͨաڈͷΠϯελϯεͱಉ
    ͡IDΛฦ͢͜ͱ͕͋Δ
    36

    View Slide

  49. ObjectIdentifier͸ɺղ์͞ΕͨաڈͷΠϯελϯεͱಉ
    ͡IDΛฦ͢͜ͱ͕͋Δ
    • ͜Ε͸ͨ·ͨ·ಉ͡ϝϞϦྖҬ͕࢖͍·Θ͞Εͨͱਪ࡯͞Ε
    Δɻ
    36

    View Slide

  50. ObjectIdentifier͸ɺղ์͞ΕͨաڈͷΠϯελϯεͱಉ
    ͡IDΛฦ͢͜ͱ͕͋Δ
    • ͜Ε͸ͨ·ͨ·ಉ͡ϝϞϦྖҬ͕࢖͍·Θ͞Εͨͱਪ࡯͞Ε
    Δɻ
    • ObjectIdentifierͷ࢓༷తʹ΋ੜଘதͷΠϯελϯεͷൺֱ
    ʢcomparisons during the lifetime of the instance.ʣΛ૝ఆͯ͠
    ͍ΔIDͳͷͰɺ͢Ͱʹղ์͞ΕͨΠϯελϯεͱಉ͡IDʹͳͬ
    ͯ͠·͏Մೳੑ͸͋ΔͱࢥΘΕΔɻ
    36

    View Slide

  51. ObjectIdentifier͕ಉ͡IDΛฦ͢͜ͱ͕͋Δ
    37

    View Slide

  52. ObjectIdentifier͕ಉ͡IDΛฦ͢͜ͱ͕͋Δ
    • ͜ͷڍಈ͕͋ͬͨͨΊɺ֘౰ͷObjectivce-Cͷؔ਺͕ҙਤ௨Γ
    ʹಈ͍ͨΓಈ͔ͳ͔ͬͨΓͯ͠ௐ͕ࠪ೉ߤͨ͠ɻ
    37

    View Slide

  53. ະղܾͳٙ໰
    38

    View Slide

  54. ະղܾͳٙ໰
    • AnyObjectͬͯͳΜͩΖ͏ʁ
    38

    View Slide

  55. ະղܾͳٙ໰
    • AnyObjectͬͯͳΜͩΖ͏ʁ
    • υΩϡϝϯτతʹ͸͢΂ͯͷΫϥε͕҉໧తʹ४ڌ͢Δ
    protocolͱهࡌ͞ΕͯΔ͕ɺఆٛΛݟΔͱ typealias
    AnyObject ʹͳ͍ͬͯΔɻ
    38

    View Slide

  56. ະղܾͳٙ໰
    • AnyObjectͬͯͳΜͩΖ͏ʁ
    • υΩϡϝϯτతʹ͸͢΂ͯͷΫϥε͕҉໧తʹ४ڌ͢Δ
    protocolͱهࡌ͞ΕͯΔ͕ɺఆٛΛݟΔͱ typealias
    AnyObject ʹͳ͍ͬͯΔɻ
    • ݕࡧ͢Δͱtypealias AnyObject = Builtin.AnyObject͕ώοτ͢
    Δɻ
    38

    View Slide

  57. ͝੩ௌ͋Γ͕ͱ͏
    ͍͟͝·ͨ͠ʂ
    QRίʔυ: Swiftͷas Any / AnyObjectͷ҉໧తͳܕม׵ʹ͍ͭͯ 39

    View Slide