Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Swiftとメタデータ
Search
noppefoxwolf
June 20, 2018
Technology
3
760
Swiftとメタデータ
SwiftとObjective-Cのruntime APIの比較と`wickwirew/Runtime`のプロパティ名取得実装の読み解きです。
noppefoxwolf
June 20, 2018
Tweet
Share
More Decks by noppefoxwolf
See All by noppefoxwolf
既存アプリをvisionOS対応してリリースした話/visionOS LT vol5
noppefoxwolf
0
160
UIのブラックボックスを探る/iOSDC23
noppefoxwolf
3
3.4k
CoreGraphicsでドット絵を描こう/iOSDC22
noppefoxwolf
0
1.9k
ランタイムデバッグのススメ/iOSDC21
noppefoxwolf
1
4.1k
google/mediapipe で始めるARアプリ開発/iOSDC2020
noppefoxwolf
1
1.3k
モバイルファーストなアプリを作るためにvearがしたこと/xRDCC
noppefoxwolf
0
85
ソーシャルライブサービスにおけるデジタル化粧の仕組みと実装/iOSDC19
noppefoxwolf
4
5.2k
Limited import clarification and its effect/tryswift2019
noppefoxwolf
2
1.1k
立ち上げ時のライブ配信アプリに最適な開発環境・技術的ノウハウとは/PocoDevMeetup-1
noppefoxwolf
0
1.2k
Other Decks in Technology
See All in Technology
Azure AI ことはじめ
tsubakimoto_s
0
130
AWS IAMのアンチパターン/AWSが考える最低権限実現へのアプローチ概略(JAWS-UG朝会#59資料改修20分版)
htan
0
330
AI研修【MIXI 24新卒技術研修】
mixi_engineers
PRO
0
130
データ分析を支える技術 生成AI再入門
ishikawa_satoru
0
380
[NIKKEI Tech Talk]Bias for Action!! 実践から学ぶための仕組とコミュニティ / Community for Practice and Learning
kanamasa
0
280
運用改善、不都合な真実 / 20240722-ssmjp-kaizen
opelab
17
8.2k
ここがすごいよ! AWS Systems Manager!
saichan11
0
1.8k
プレイドにおけるDatadog APMの活用方法
plaidtech
PRO
2
120
技術負債による事業の失敗はなぜ起こるのか / Why do business failures due to technical debt occur?
i35_267
0
190
ゆめみのアクセシビリティの現在地と今後
ryokatsuse
3
290
初中級者用如何使用backlog -VALE TUDOEDITION-
in0u
0
140
楽しくGoを学び合う、LayerXの勉強会文化 / LayerX's study culture of having fun and learning Go together
ar_tama
2
350
Featured
See All Featured
How to name files
jennybc
67
96k
GitHub's CSS Performance
jonrohan
1026
450k
Creatively Recalculating Your Daily Design Routine
revolveconf
214
11k
Documentation Writing (for coders)
carmenintech
63
4.2k
Leading Effective Engineering Teams 2024
addyosmani
3
300
Side Projects
sachag
451
42k
Music & Morning Musume
bryan
43
5.9k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
149
45k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
129
32k
Mobile First: as difficult as doing things right
swwweet
219
8.8k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
360
22k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
662
120k
Transcript
4XJGUͱϝλσʔλ 4XJGUѪձWPM ! !OPQQFGPYXPMG
OPQQF ! ͖ͭͶ͕͖ʂʂ " J04ΞϓϦ։ൃ 4XJGUѪձॳࢀઓ ! !OPQQFGPYXPMG
! !OPQQFGPYXPMG
ϝλσʔλͱ ϝλใͱɺ͢ͳΘͪσʔλʹ͍ͭͯͷσʔλͱ͍͏ ҙຯͰɺ͋Δσʔλ͕ਵͯ࣋ͭͦ͠ͷσʔλࣗʹͭ ͍ͯͷՃతͳσʔλΛࢦ͢ɻʢ8JLJௐʣ ! IUUQTKBXJLJQFEJBPSHXJLJϝλσʔλ ! !OPQQFGPYXPMG
ϝλσʔλͱ ‣ Ϋϥε໊ ‣ ΫϥεͷϓϩύςΟ໊ ‣ ܧঝݩ ‣ ४ڌ͍ͯ͠Δϓϩτίϧ FUD
! !OPQQFGPYXPMG
ϝλσʔλ͕ඞཁͳ࣌ ‣ ࠓݟ͍ͯΔϏϡʔίϯτϩʔϥΛϩάʹు͖͍ͨ ‣ ΠϯελϯεΛμϯϓͯ͠อଘ͍ͨ͠ ‣ ৄࡉͰ͔Γ͍͢ΤϥʔΛද͍ࣔͨ͠ ‣ ͍͍ײ͡ͷ03.࡞Γ͍ͨͱ͔ FUD
! !OPQQFGPYXPMG
4XJGUͰϝλσʔλΛऔಘ͢ΔʹͲ͏͢Ε͍͍ʁ ! !OPQQFGPYXPMG
ͦ͏͍͑0CKFDUJWF$ͰͲ͏͍ͯͨ͠ͷ͔ʁ ! !OPQQFGPYXPMG
ϓϩύςΟҰཡΛऔಘ͢Δ 0CKFDUJWF$SVOUJNF"1* class_copyPropertyList(_:_:) IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPO PCKFDUJWFDDMBTT@DPQZQSPQFSUZMJTU ! !OPQQFGPYXPMG
ϓϩύςΟҰཡΛऔಘ͢Δ unsigned int propertyCount = 0; objc_property_t * properties =
class_copyPropertyList([self class], &propertyCount); NSMutableArray * propertyNames = [NSMutableArray array]; for (unsigned int i = 0; i < propertyCount; ++i) { objc_property_t property = properties[i]; const char * name = property_getName(property); [propertyNames addObject:[NSString stringWithUTF8String:name]]; } free(properties); NSLog(@"Names: %@", propertyNames); ! !OPQQFGPYXPMG
ϓϩύςΟҰཡΛऔಘ͢Δ 0CK$SVOUJNF"1*4XJGUͰ͏͜ͱ͕Ͱ͖Δɻ import ObjectiveC ! !OPQQFGPYXPMG
ϓϩύςΟҰཡΛऔಘ͢Δ var count: UInt32 = 0 let properties = class_copyPropertyList(MyClass.self,
&count) for i in 0..<Int(count) { let prop = properties![i] let propName = String(cString: property_getName(prop)) print(propName) } ! !OPQQFGPYXPMG
ϓϩύςΟҰཡΛऔಘ͢Δ 4XJGUͰDMBTT@DPQZ1SPQFSUZ-JTUΛ͏ʹ੍ݶ͕͋Δ class MyClass: NSObject { @objc var prop1 =
"" @objc var prop2 = "" } ϓϩύςΟʹ@objcΛ͚ͭΔ͜ͱʂ˞ ˞!PCKD͕ඞཁͰ͋Γɺ/40CKFDUΛܧঝ͢Δඞཁͳ͍ɻ·ͨ!PCKDΛ͚ͭΔʹDMBTTͰ͋Δඞཁ͕͋Δ ! !OPQQFGPYXPMG
!PCKDΛ͚ͣʹϓϩύ ςΟҰཡΛऔಘ͢Δํ๏ ͳ͍Ͱ͠ΐ͏͔ʜʁ ! !OPQQFGPYXPMG
ϓϩύςΟҰཡΛऔಘ͢Δ &ODPEBCMF class MyClass: Encodable { var prop1 = ""
var prop2 = "" } let data = try! JSONEncoder().encode(MyClass()) let json = try! JSONSerialization.jsonObject(with: data, options: .allowFragments) print((json as! [String : Any]).keys) ‣ <QSPQ QSPQ> ! !OPQQFGPYXPMG
SFqFDUJPO let mirror = Mirror(reflecting: MyClass()) let propNames = mirror.children.compactMap({
$0.label }) ! !OPQQFGPYXPMG
0CKFDUJWF$SVOUJNF "1*ʹ૬͢Δ GSBNFXPSLແ͍ͷ͔ʜ ! !OPQQFGPYXPMG
TXJGUEPDT3VOUJNFNE 5IFpOBMSVOUJNFJOUFSGBDFJTDVSSFOUMZ BXPSLJOQSPHSFTT ͳͦ͞͏ IUUQTHJUIVCDPNBQQMFTXJGUCMPCNBTUFSEPDT3VOUJNFNE ! !OPQQFGPYXPMG
5IJSEQBSUZSVOUJNF"1* IUUQTHJUIVCDPNXJDLXJSFX3VOUJNF IUUQTHJUIVCDPN;FXP3FqFDUJPO ! !OPQQFGPYXPMG
XJDLXJSFX3VOUJNF var md = ClassMetadata(type: MyClass<Int>.self) let info = md.toTypeInfo()
info.properties.compactMap { $0.name } ! !OPQQFGPYXPMG
1SPT$POT !PCKD JOTUBODF NFUBEBUB 0CK$SVOUJNF Y P P &ODPEBCMF P
Y Y SFqFDUJPO P Y ˚ UIJSEQBSUZBQJ P P P ! !OPQQFGPYXPMG
☺ ͡Ό͋5IJSEQBSUZͷ͓͏ʙʙ ! !OPQQFGPYXPMG
3VOUJNF3FqFDUJPO Ͳ͏ͬͯϝλσʔλΛऔ ಘ͍ͯ͠Δͷ͔ʁ ! !OPQQFGPYXPMG
3VOUJNFͷॲཧ 5ZQF͕อ࣋͞Ε͍ͯΔϝϞϦΛࢀরͯ͠ϝλσʔ λΛऔಘ͍ͯ͠Δɻ ͜ΕΒΛߏମʹͯቕΊ͍͍ͯ͢Α͏ʹͨ͠ϥΠ ϒϥϦ ϝϞϦͷϨΠΞτߏυΩϡϝϯτ͕͋Δ ! !OPQQFGPYXPMG
! !OPQQFGPYXPMG
! !OPQQFGPYXPMG
45&1 var type: Any.Type = Kind.self let typeAsPointer = unsafeBitCast(type,
to: UnsafeMutablePointer<Int64>.self) let metadataPointer = typeAsPointer.advanced(by: -1) let metadataRawPointer = UnsafeMutableRawPointer(metadataPointer) UZQFࣗମͷϙΠϯλ͔ΒੜϙΠϯλΛऔಘ͢Δ ! !OPQQFGPYXPMG
! !OPQQFGPYXPMG
<ิ>WBMVFXJUOFTTUBCMF ؔΛݺͼग़࣌͢ʹܦ༝͢Δςʔϒϧ 3VOUJNFͰ͜ͷαΠζॱংΛݩʹΠϯελϯεͷϝ ϞϦߏΛ࡞Γग़ͯ͠ແཧΓੜ͢Δػೳ͕͋Δ ! !OPQQFGPYXPMG
45&1 let layout = metadataRawPointer.assumingMemoryBound(to: StructMetadataLayout.self) assumingMemoryBoundͰϙΠϯλΛ .FUBEBUB-BZPVUͷߏͷϙΠϯλͱղऍ͠·͢ɻ ! !OPQQFGPYXPMG
45&1 4USVDU.FUBEBUB-BZPVUTXJGU struct StructMetadataLayout: NominalMetadataLayoutType { var valueWitnessTable: UnsafePointer<ValueWitnessTable> var
kind: Int var nominalTypeDescriptor: UnsafeMutablePointer<NominalTypeDescriptor> } ! !OPQQFGPYXPMG
45&1 structLayout.kind //1 enumLayout.kind //2 protocolLayout.kind //12 ͜ΕͰϝϞϦͷߏΛTUSVDUʹϚοϐϯά͢Δࣄ͕ग़དྷ ͨ !
!OPQQFGPYXPMG
45&1 Nominal Type Descriptorͷoffset: ͕̐field namesͳͷͰͦ͜ͷ࣮ମΛࢀর͢ΔͱɺϓϩύςΟ໊ͷ $4USJOHͷྻ͕औಘͰ͖Δɻ ! !OPQQFGPYXPMG
45&1 struct Animal { var name: String } let cString
= metadata.pointee.nominalTypeDescriptor.pointee.fieldNames.advanced() String(cString: cString) → name $4USJOHͷࢀরΛ4USJOHʹม͢ΔͱɺϓϩύςΟ໊͕ औಘͰ͖Δɻ ! !OPQQFGPYXPMG
45&1 ͋ͱ͜ͷ$4USJOHͷࢀরΛϓϩύςΟζϥͯ͠औಘ ͍͚ͯ͠ɺશͯͷϓϩύςΟ໊͕औಘͰ͖Δɻ ࣮ࡍଞͷϙΠϯλ͔ΒϓϩύςΟͷΛऔಘͯͦ͠ͷΛऔಘ͍ͯ͠Δ ! !OPQQFGPYXPMG
8BSOJOH ͜ͷํ๏વ4XJGUͷ༷มߋͰϝϞϦͷϨΠΞτ ͕มΘΔͱ͑ͳ͘ͳΔɻ 4XJGU"#*4UBCJMJUZ.BOJGFTUP IUUQTHJUIVCDPNBQQMFTXJGUCMPCNBTUFSEPDT"#*4UBCJMJUZ.BOJGFTUPNE ! !OPQQFGPYXPMG
&YBNQMFQSPKFDU IUUQTHJUIVCDPNOPQQFGPYXPMG.FUBEBUB&YBNQMF ! !OPQQFGPYXPMG
·ͱΊ ‣ ϝλσʔλʹΞΫηε͢Δํ๏ෳ͋ΓҰҰ Ͱ͋Δ ‣ ७4XJGUͳߏମͷ.FUBEBUBΛ҆શʹಘΔํ๏· ͩແ͍ɻ ‣ ϝϞϦΛࢀর͢ΔࣄͰɺ௨ৗऔಘग़དྷͳ͍ଟ͘ͷ ใʹΞΫηεͰ͖Δ
! !OPQQFGPYXPMG