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. ໰୊1 let int: Int = 0 print(type(of: int)) // Int

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

    print(type(of: int as AnyObject)) // __NSCFNumber __NSCFNumber ≒ NSNumber 4
  3. ౴͑2 let string = "" print(type(of: string)) // String print(type(of:

    string as AnyObject)) // __NSCFConstantString __NSCFConstantString ≒ NSString 6
  4. ໰୊3 struct StructModel {} let structModel = StructModel() type(of: structModel)

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

    // StructModel type(of: structModel as AnyObject) // __SwiftValue __SwiftValue 10
  6. 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
  7. if !done, let wrapper = source as? _Unwrappable { if

    let value = wrapper._unwrap() { result = value as AnyObjectɹ// ← ʂʂʂ } else { result = _nullPlaceholder } done = true } 15
  8. 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
  9. __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
  10. __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
  11. ໰୊4 /* Objective-C */ @interface ObjCModel : NSObject - (NSString

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

    test(_ any: Any!) -> String! } 20
  13. 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
  14. SwiftͰͷidܕͷѻ͍ Objective-C Swift 2 Swift 3 id AnyObject Any •

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

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

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

    Objective-CͷAnyܕʹ஋Λ౉͢ͱ as AnyObject ͱಉ͘͡ func _bridgeAnythingToObjectiveC<T>(_ x: T) -> AnyObjectʹΑΔܕม ׵͕ߦΘΕΔ͜ͱʹͳΔɻ 28
  18. Πϯελϯε͕ҟͳΔ͜ͱΛݕূ struct StructModel {} let structModel = StructModel() Timer.scheduledTimer( withTimeInterval:

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

    struct ObjectIdentifier(0x000060000055dba0) struct ObjectIdentifier(0x000060000055ef80) struct ObjectIdentifier(0x00006000005557c0) // ಉ͡IDʂʂʂ */ 35