Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

ੁݪ ༞ @yusuga_ 2

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

__SwiftValue ! 11

Slide 12

Slide 12 text

ղઆ 12

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

__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

Slide 22

Slide 22 text

__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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

Anyͳͷʹʁ ! 23

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

࣮ࡍʹૺ۰ͨ͠໰୊ 29

Slide 38

Slide 38 text

࣮ࡍʹૺ۰ͨ͠໰୊ 30

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

࣮ࡍʹૺ۰ͨ͠໰୊ 31

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

ະղܾͳٙ໰ 38

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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