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

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

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

Df8bc8c531e2c5c89c1a007db1cf79a3?s=128

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
  2. ੁݪ ༞ @yusuga_ 2

  3. ໰୊1 let int: Int = 0 print(type(of: int)) // Int

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

    print(type(of: int as AnyObject)) // __NSCFNumber __NSCFNumber ≒ NSNumber 4
  5. ໰୊2 let string = "" print(type(of: string)) // String print(type(of:

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

    string as AnyObject)) // __NSCFConstantString __NSCFConstantString ≒ NSString 6
  7. ͳ͔ͥObjectice-Cܥͷܕʹ ม׵͞Ε͍ͯΔͧʂ ! 7

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

    as! Int) // Int 8
  9. ໰୊3 struct StructModel {} let structModel = StructModel() type(of: structModel)

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

    // StructModel type(of: structModel as AnyObject) // __SwiftValue __SwiftValue 10
  11. __SwiftValue ! 11

  12. ղઆ 12

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

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

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

    _bridgeAnythingToObjectiveC<T>(_ x: T) -> AnyObjectͰߦΘΕ͍ͯΔɻ 13
  16. public func _bridgeAnythingToObjectiveC<T>(_ 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
  17. if !done, let wrapper = source as? _Unwrappable { if

    let value = wrapper._unwrap() { result = value as AnyObjectɹ// ← ʂʂʂ } else { result = _nullPlaceholder } done = true } 15
  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
  19. SwiftͱObjective-Cͷܕͷ૬ޓม׵ 17

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

    17
  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
  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
  23. ໰୊4 /* Objective-C */ @interface ObjCModel : NSObject - (NSString

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

    test(_ any: Any!) -> String! } 20
  25. ໰୊4 let objcModel = ObjCModel() type(of: objcModel) // ObjCModel objcModel.test(StructModel())

    // ԿʹͳΔʁ 21
  26. ౴͑4 let objcModel = ObjCModel() type(of: objcModel) // ObjCModel objcModel.test(StructModel())

    // __SwiftValue __SwiftValue 22
  27. Anyͳͷʹʁ ! 23

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

    // StructModel 24
  29. SwiftͰͷidܕͷѻ͍ Objective-C Swift 2 Swift 3 id AnyObject Any NSArray

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

  31. SwiftͰͷidܕͷѻ͍ Objective-C Swift 2 Swift 3 id AnyObject Any •

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

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

  34. SwiftͰͷidܕͷѻ͍ Objective-C Swift 2 Swift 3 id AnyObject Any •

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

  36. SwiftͰͷidܕͷѻ͍ Objective-C Swift 2 Swift 3 id AnyObject Any •

    Objective-CͷAnyܕʹ஋Λ౉͢ͱ as AnyObject ͱಉ͘͡ func _bridgeAnythingToObjectiveC<T>(_ x: T) -> AnyObjectʹΑΔܕม ׵͕ߦΘΕΔ͜ͱʹͳΔɻ 28
  37. ࣮ࡍʹૺ۰ͨ͠໰୊ 29

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

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

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

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

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

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

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

    ʹҧ͏IDʹͳΔ͜ͱ͕֬ೝͰ͖Δɻ 32
  45. Πϯελϯε͕ҟͳΔ͜ͱΛݕূ struct StructModel {} let structModel = StructModel() Timer.scheduledTimer( withTimeInterval:

    1, repeats: true ) { _ in // 1ඵ͝ͱʹΫϩʔδϟ͕࣮ߦ͞ΕΔ print("struct", ObjectIdentifier(structModel as AnyObject)) } 33
  46. /* ग़ྗ͞ΕΔϩά struct ObjectIdentifier(0x00006000005749c0) struct ObjectIdentifier(0x000060000055ef80) struct ObjectIdentifier(0x00006000005557c0) struct ObjectIdentifier(0x000060000055dba0)

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

    struct ObjectIdentifier(0x000060000055dba0) struct ObjectIdentifier(0x000060000055ef80) struct ObjectIdentifier(0x00006000005557c0) // ಉ͡IDʂʂʂ */ 35
  48. ObjectIdentifier͸ɺղ์͞ΕͨաڈͷΠϯελϯεͱಉ ͡IDΛฦ͢͜ͱ͕͋Δ 36

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

  50. ObjectIdentifier͸ɺղ์͞ΕͨաڈͷΠϯελϯεͱಉ ͡IDΛฦ͢͜ͱ͕͋Δ • ͜Ε͸ͨ·ͨ·ಉ͡ϝϞϦྖҬ͕࢖͍·Θ͞Εͨͱਪ࡯͞Ε Δɻ • ObjectIdentifierͷ࢓༷తʹ΋ੜଘதͷΠϯελϯεͷൺֱ ʢcomparisons during the

    lifetime of the instance.ʣΛ૝ఆͯ͠ ͍ΔIDͳͷͰɺ͢Ͱʹղ์͞ΕͨΠϯελϯεͱಉ͡IDʹͳͬ ͯ͠·͏Մೳੑ͸͋ΔͱࢥΘΕΔɻ 36
  51. ObjectIdentifier͕ಉ͡IDΛฦ͢͜ͱ͕͋Δ 37

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

  53. ະղܾͳٙ໰ 38

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

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

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

    ݕࡧ͢Δͱtypealias AnyObject = Builtin.AnyObject͕ώοτ͢ Δɻ 38
  57. ͝੩ௌ͋Γ͕ͱ͏ ͍͟͝·ͨ͠ʂ QRίʔυ: Swiftͷas Any / AnyObjectͷ҉໧తͳܕม׵ʹ͍ͭͯ 39