Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Swiftとメタデータ
Search
noppefoxwolf
June 20, 2018
Technology
880
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Swiftとメタデータ
SwiftとObjective-Cのruntime APIの比較と`wickwirew/Runtime`のプロパティ名取得実装の読み解きです。
noppefoxwolf
June 20, 2018
More Decks by noppefoxwolf
See All by noppefoxwolf
柔軟性のあるUIで、多くの環境でアプリを活躍させる/iOSDC26
noppefoxwolf
0
700
High performance GIF playback/iOSDC25
noppefoxwolf
1
670
Spice up your notifications/try!Swift25
noppefoxwolf
3
850
iOSの隠されたAPIを解明し、開発効率を向上させる方法/iOSDC24
noppefoxwolf
2
1.4k
今から理解するApp Intentエコシステム/WWDC24Recap
noppefoxwolf
0
79
既存アプリをvisionOS対応してリリースした話/visionOS LT vol5
noppefoxwolf
0
230
UIのブラックボックスを探る/iOSDC23
noppefoxwolf
3
5.2k
CoreGraphicsでドット絵を描こう/iOSDC22
noppefoxwolf
0
3.3k
ランタイムデバッグのススメ/iOSDC21
noppefoxwolf
1
5.7k
Other Decks in Technology
See All in Technology
安心して変更できるWebフロントエンドの作り方
pirosikick
5
2.7k
アプリをもっと"iOSアプリっぽく"する小さな工夫 / Small Touches That Make Your App Feel More Like an iOS App
matsuji
2
950
作って終わりじゃないサーバーレス 〜9年運用する大規模EC物流API基盤の設計・運用のリアル〜
zozotech
PRO
0
160
ADKで始める業務改善 - AIエージェント開発時の考えと設計
harappa80
2
200
AI時代、データエンジニアが一番おもろい
genshun9
0
670
The Knowledge Spine: A Machine-Executable Ontology for Governed Marketing Activation
vananth22
0
100
.NET WebAssemblyで実現するクライアントサイドAI推論:NuGetからViteまで、2つのエコシステムを繋ぐビルド戦略
yamachu
0
130
現場で役立つ技術負債の効果的な返済方法
masuda220
PRO
9
4.5k
10Xに技術的負債をもたらした「2つの境界の歪み」その構造と解消への営み
10xinc
0
2.1k
人間はどの意思決定を手放せるのか
kawasima
15
7.3k
Railsのように考える: See through the Master
snoozer05
PRO
4
1.1k
目の前の楽しいが人生を変える - コミュニティの螺旋の歩き方と楽しむコツ / change your life
soudai
PRO
5
640
Featured
See All Featured
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
420
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
320
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
730
The Cost Of JavaScript in 2023
addyosmani
55
10k
Documentation Writing (for coders)
carmenintech
77
5.5k
The agentic SEO stack - context over prompts
schlessera
0
940
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
280
XXLCSS - How to scale CSS and keep your sanity
sugarenia
250
1.3M
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
4.8k
Being A Developer After 40
akosma
91
590k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.7k
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