Your SlideShare is downloading. ×
0
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Cocoaアプリに無理矢理プラグインを導入する入門
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Cocoaアプリに無理矢理プラグインを導入する入門

1,062

Published on

既存のアプリが微妙に使いにくい?そんなときは!自作のプラグインで改造できるニャー

既存のアプリが微妙に使いにくい?そんなときは!自作のプラグインで改造できるニャー

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,062
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
4
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Super Simple Cocoa Plugin Introduction nendoki
  • 2. コレって誰よ 上田 宗一郎(うえだ ソウイチロウ) id: nendoki (a.k.a ne[tab]) 京都大学大学院情報学研究科M1 親の代からMac使い
  • 3. mac? スタバドヤ顔マン御用達アイテムNo1 パロアルト研究所からアイディア持ち出したアレ ディスプレイ上のサイズ=印刷サイズで有名
  • 4. 本日話す事 コレがしたい 前提のお話 今回必要となる技術 実際にアプリを見てみよう
  • 5. 本日話す事 コレがしたい 前提のお話 今回必要となる技術 実際にアプリを見てみよう
  • 6. Macアプリ作ってますか?
  • 7. Q. 今使っているプログラム が*微妙に*機能不足だ
  • 8. Windows的解法 フリーウェアに 良いのがあるよ!!
  • 9. 富豪的解法 金を払えば良い
  • 10. プログラマ的解法 自分で作る
  • 11. FSF的解法 GPLコード片が 埋め込まれていないか探す
  • 12. よりよい解法 既存のアプリを修正しよう
  • 13. という事で Mac用Cocoaアプリケーションに自分で機能を追加 して幸せを得よう
  • 14. 本日話す事 コレがしたい 前提のお話 今回必要となる技術 実際にアプリを見てみよう
  • 15. 前提のお話 Objective-Cってなんそ ObjC流記法 Cocoa Framework
  • 16. 前提のお話 Objective-Cってなんそ ObjC流記法 Cocoa Framework
  • 17. Objective-C! || C + SmallTalk
  • 18. SmallTalkな箇所のみ解説します
  • 19. メッセージ呼び出し メンバメソッドの呼び出しの事 メッセージ 単項メッセージ キーワード付きメッセージ 二項メッセージ(SmallTalkのみ 可変長引数や部分的にキーワードの無いメッセージは省略
  • 20. 単項メッセージ [obj message]; 他言語のobj.message()に対応 キーワード付きメッセージ [obj message:arg0 key1: arg1 key2:arg2 ..]; 他言語ではobj.message(arg0, arg1, arg2…)とか obj.message(arg0, key1=arg1, key2=arg2, …)に対応
  • 21. クラスの定義(ObjC固有) @interfaceでインターフェース定義(ヘッダー) @imprementsで実装を定義(ボディー) インスタンスメソッド - (型)methodName:(型)arg0 key1:(型)arg1; クラスメソッド + (型)methodName:(型)arg0 key1:(型)arg1;
  • 22. @interface AGSampleLayer : CALayer { CALayer *floorLayer; } + (id)layer - (void)resizeWithSize:(CGSize)size; @end ! @implementation AGSampleLayer + (id)layer { … return self; } ! - (void)resizeWithSize:(CGSize)size { … } @end
  • 23. カテゴリ クラス定義を複数回に分けて記述 既存のクラスに動的にメソッド追加が可能 フレームワークのクラスにも可能 実装を機能別に別のヘッダーに…なんてことも
  • 24. オーバーロードについて オーバーロードは存在しない メッセージ名を変える事で区別 メッセージ名にはキーワードを含める -(id)initWithFrame:(NSRect)frame style:(ViewStyle)style 識別子:-initWithFrame:style:
  • 25. 良くある例 -(id)init -(id)initWithData:(NSData *)data -(id)initWithData:(NSData *)data withSize:(int)size それぞれ別の識別子のため問題無し 返り値の型を合わせるのはマナー
  • 26. id? 特殊な型id 全てのオブジェクト型から暗黙のキャスト可能 存在しないメッセージは無視される コンパイルエラーにはならない 要するに任意のメッセージを受ける事を主張した Object *と覚えておこう
  • 27. 前提のお話 Objective-Cってなんそ ObjC流記法 Cocoa Framework
  • 28. クラス名について Objective-Cには名前空間が無い 元ネタのC言語には無いから仕方ないね そこで関数/クラス名に二文字程度の識別子を使う NSObject (NextStep Famework由来のため) CGRect (CoreGraphicsの機能のため)
  • 29. インスタンス化 インスタンスを「作る」メッセージ +alloc インスタンスを「初期化する」メッセージ -init -initWithHoge:
  • 30. 実際に使う場合 NSDate *date = [[NSDate alloc] init]; 現在時刻で初期化 NSImage *img = [[NSImage alloc] initWithData:bin]; 指定したデータで画像オブジェクトを作成
  • 31. -initの書き方 親の-initを明示的に呼び出し、自身に代入 返り値も自分自身とする - (id)init { if(self = [super init]) { // 初期化コードを記入 } return self; }
  • 32. インターフェースの実現 あるメソッドを実装している事を期待したい 1. @protocolを利用する 速度を気にしない限り使わない 2.NSObjectをカテゴリで拡張する ルートオブジェクトが既に実装済み = 子クラスの対応は任意
  • 33. getter/setter int hogeなメンバ変数を持つとする getter -(int)hoge setter -(void)setHoge:(int)newhoge ObjC2.0から@propertyによってこの2つは自動生成可能に
  • 34. 前提のお話 Objective-Cってなんそ ObjC流記法 Cocoa Framework
  • 35. Cocoa Framework? Macアプリケーションの基本ライブラリ Cocoa Frameworkは複数のフレームワークの集合 Foundation Framework Appkit Framework Coredata Framework
  • 36. 標準ライブラリは? Foundation Frameworkが提供するもの NSObject NSArray NSString NSDictionary and so on..
  • 37. 言語の基本的な機能が集まっている NSObject? 全てのクラスのルートクラス 他のフレームワークも必ず依存している …事になっている
  • 38. AppKit? Appkit Framwork アプリケーションのビュー イベント処理 AppleScript ランループとかもここから
  • 39. 本日話す事 コレがしたい 前提のお話 今回必要となる技術 実際にアプリを見てみよう
  • 40. 本日使う技術 アプリに侵入しよう! アプリを理解しよう! アプリを乗っ取ろう! アプリを操作しよう!
  • 41. 本日使う技術 アプリに侵入しよう! アプリを理解しよう! アプリを乗っ取ろう! アプリを操作しよう!
  • 42. で、どうやって侵入するの
  • 43. 古い方法 IMのフリをする /Library/InputManagers Cocoaアプリは必ずこのフォルダにある実行 ファイルを無条件にロードしていた 今は駄目です
  • 44. SIMBLに頼ろう SIMple Bundle Loader Cocoaアプリに外部プラグインをロードさせる /Library/Application Support/SIMBL/Plugins
  • 45. 使い方 Info.plist(アプリケーション設定ファイル)に記述 SIMBLTargetApplicationsキーで、以下の辞書の配列を 設定 BundleIdentifier: 対象アプリ MaxBundleVersion: 読ませる最大バージョン MinBundleVersion: 対応する最小のバージョン
  • 46. +(void)loadを実装する プラグインが読み込まれた際に必ず呼ばれるメッ セージ シングルトンインスタンスを返す実装が望まし い 複数回呼ばれる場合がある -initのつもりで書いてはだめ
  • 47. SIMBLはIMじゃないの? AppleScriptを侵入経路として使っているらしい IMを使う方法は最新ではない
  • 48. 準備 1. アプリケーションの起動監視アプリを用意 2. AppleEvent Handlerアプリを別途用意 手順 1. アプリの起動を検知 2. 起動したアプリに対して、Handlerを起動するAppleEvent を送信 3. HandlerはSIMBLプラグインを読み込む
  • 49. 本日使う技術 アプリに侵入しよう! アプリを理解しよう! アプリを乗っ取ろう! アプリを操作しよう!
  • 50. で、何を書き換えればいいの?
  • 51. 侵入したそのあとに 「侵入してもグローバル変数しか書き換えられま せん」では意味が無い しかも書き換えられるグローバル変数すら分か らない せめて乗っ取れる機能とか調べたいよね
  • 52. ここで問題だ バイナリの固まりであるアプリケーションから
 どうやってAPIを見つけ出すか 1. ハンサムなデバッガが突如ソレらしいメソッド を発見してくれる 2. それっぽいツールが助けてくれる 3. 何も無い、現実は非常である
  • 53. 1を試す 1.XCode.appを起動する 2.対象アプリにアタッチし、無 理矢理停止する 3.目標の関数が起動しそうなイ ベントを発火させる 4.Step & Trace!
  • 54. (僕には)無理でした (努力次第ではなんとかなりそう)
  • 55. 2を試す あー、どこかにコマンド一発で@interface情報をま とめてくれる便利なコマンド無いかなー カテゴリとかもちゃんと区別して出力してくれる と良いなー メンバ変数とかプライベートメソッドとか出力さ れたら言う事無いんだけどなー
  • 56. Class-dump http://stevenygard.com/projects/class-dump/ command-line utility for examining the Objective-C runtime information stored in Mach-O files.
  • 57. Usage: class-dump [options] <mach-o-file> -C <regex> 正規表現にマッチするもののみを 出力 -H ヘッダーファイルとして出力 -r 共有ライブラリも出力 --sdk-root SDKのパスを指定
  • 58. Dock.appで試す class-dump /System/Library/CoreServices/Dock.app/ Contents/MacOS/Dock -H --sdk-root /Applications/ Xcode.app/Contents/Developer/Platforms/ MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -H: ヘッダーファイルとして出力 --sdk-root: ヘッダーファイルにシステムのフ レームワークを含めない
  • 59. CALayer- CALayerAdditions.h CALayer- ECModalEventDeleg ate.h CDStructures.h DBAttachedWindow .h DBDebugWidgetPro cess.h DBDebugWidgetSer ver.h DBRippleInfo.h DBSpringboard.h DBWidget.h DBWidgetProcess.h DOCKAppDeathEve nt.h DOCKAppHideEvent. h DOCKAppLaunchCo mpleteEvent.h DOCKAppLaunchEv ent.h DOCKAppNeedsAtte ntionEvent.h DOCKAppRevealEve nt.h DOCKAutoHideDisa bledEvent.h DOCKAutoHideEnab ledEvent.h DOCKBlockEvent.h DOCKBounceEvent. h DOCKDashboardTile .h DOCKDesktopTile.h DOCKDisplayChang edEvent.h DOCKDownloadDire ctory.h DOCKDownloadMan ager.h DOCKDownloadPro gressHandler- Protocol.h DOCKDragDropEven t.h DOCKDragEnterEve nt.h DOCKDragLeaveEve nt.h DOCKDynamicFolde r.h DOCKEvent.h DOCKExtraDelegate -Protocol.h DOCKFileTile.h DOCKFileTileFactory .h DOCKFloorLayer.h DOCKFloorShadowL ayer.h DOCKFolder.h DOCKFolderTile.h DOCKFolderTileCac heEntry.h DOCKGestureDefaul tHandler.h DOCKGestureEvent. h DOCKGestureHandl er-Protocol.h DOCKGestures.h DOCKGlassFloorLay er.h DOCKGridLayer.h DOCKIndicatorLayer .h DOCKInsertTile.h DOCKInstallAddOpe ration.h DOCKInstallMoveOp eration.h DOCKInstallOperati on.h DOCKInstallRemove Operation.h DOCKInstallTransac tion.h DOCKInstallUpdate Operation.h DOCKInternalDropE vent.h DOCKLabelLayer.h DOCKMaximizeWin dowEvent.h DOCKMaximizeWin dowWithOrderEvent .h DOCKMaximizeWin dowsEvent.h DOCKMiniView.h DOCKMiniViewLayer .h DOCKMinimizedWin dow.h DOCKMinimizedWin dowEvent.h DOCKMinimizedWin dowsEvent.h DOCKMouseEnterEv ent.h DOCKMouseLeaveE vent.h DOCKOrientationCh angedEvent.h DOCKPSNEvent.h DOCKPeriodicMess ageTrace.h DOCKPreferences.h DOCKProcessTile.h DOCKRecentsContr oller.h DOCKRecentsModel .h DOCKRecentsTile.h DOCKReflectionLay er.h DOCKRemoveWindo wsEvent.h DOCKScreenSharin gModel.h DOCKScreenSharin gTile.h DOCKSeparatorTile. h DOCKSetWindowTitl eEvent.h DOCKSideGlassFloo rLayer.h DOCKSmartFolderTi le.h DOCKSpacerTile.h DOCKStack.h DOCKStackActionH andling-Protocol.h DOCKStackActionS ender-Protocol.h DOCKStackAnimato r.h DOCKStackBackgro undLayer.h DOCKStackBlurWin dow.h DOCKStackCollapse dDataSource- Protocol.h DOCKStackDataSou rceClient-Protocol.h DOCKStackExpande dDataSource- Protocol.h DOCKStackExpande dHandler.h DOCKStackExpande dItemLayer.h DOCKStackExpande dLayer.h DOCKStackFanAnim ator.h DOCKStackFanItem Layer.h DOCKStackFanLaye r.h DOCKStackGoBack ButtonLayer.h DOCKStackGridAni mator.h DOCKStackGridHov erLayer.h DOCKStackGridItem Layer.h DOCKStackGridLaye r.h DOCKStackItem- Protocol.h DOCKStackLayer.h DOCKStackListAnim ator.h DOCKStackListItem Layer.h DOCKStackListLaye r.h DOCKStackPreview. h DOCKStaticScreenS haringModel.h DOCKTileEvent.h DOCKTileLabelLayer .h DOCKTileLayer.h DOCKTileRemovedE vent.h DOCKTileShadowLa yer.h DOCKTrashTile.h DOCKURLTile.h DOCKUpdateMinimi zedWindowEvent.h DOCKWindowCopy. h DOCKWindowEvent. h DOCKWindowTile.h DOCKWindowUnreg isteredEvent.h DPAnimationTimer. h DPBackgroundDesk topPicture.h DPBackgroundDesk topPictureInfo.h DPColorSpace.h DPDefaultPictureInf o.h DPDesktopPicture.h DPDesktopPictureM anager.h DPDesktopWindow- Protocol.h DPDirectoryFileListi ng.h DPDummyRenderO bject.h DPFileListing.h DPPictureInfo.h DPPictureStorage.h DPRemoteConnecti on.h DPSharedDesktopI mage.h DPSharedSlot.h DPStatementCache. h DPTiledPictureInfo. h DPWakeupSource.h DPiLifeFileListing.h DRAGTimerInfo.h DockExtra- Protocol.h DockExtra.h DockExtraManager. h DockExtraServer.h DockNotificationCe nter.h ECAlertPanel.h ECAlertPanelDelega te-Protocol.h ECAliasHandle.h ECButtonLayer.h ECCalloutLayer.h ECConsedEvent.h ECCoverFlow.h
  • 60. 無数にソレっぽいファイルが出て来た 概観すると4つくらいの名前空間が見える WVSystemSpace.h LPAppManager.h ECCoverFlowItemLayer.h DOCKStackListLayer.h
  • 61. WV系はなぜかSpacesっぽい名前のクラスが多い? ソレらしいメンバ変数を持つクラスを乗っ取れば 操作が出来るに違いない ソレらしいイベントリスナーを持つクラスを乗っ 取れば、イベントドリブンが成立するに違いない
  • 62. 本日使う技術 アプリに侵入しよう! アプリを理解しよう! アプリを乗っ取ろう! アプリを操作しよう!
  • 63. おまたせしました 乗っ取りのお時間です
  • 64. 乗っ取り乗っ取り言うけどさ 具体的な乗っ取り手法って? poisng(古い) method swizzling(新しい)
  • 65. まずはpoisngから posing: 「クラステーブルを書き換えることでクラ スの実体を置き換える技法。」 via Wikipedia 既存のクラスを実行時に置き換える手法らしい
  • 66. ClassAをClassBでposingを用いて乗っ取る例 制限 ClassBはClassAの直接のサブクラスであること ClassBはメンバ変数を持たないこと ClassAのインスタンスが存在しないこと
  • 67. 図 ClassA instanceA2instanceA1 posing ClassB instanceA2instanceA1 ClassA
  • 68. poseAsClass:によって実現できた 現在(ObjC2.0)では推奨されない
  • 69. Method Swizzling メソッドの実装を動的に入れ替える技法 libobjcランタイムでサポート ObjC2.0でも動作
  • 70. libobjcの関数群 Method class_getInstanceMethod(Class aClass, SEL aSelector) Classからインスタンスメソッドを取得 Method class_getClassMethod(Class aClass, SEL aSelector) Classからクラスメソッドを取得
  • 71. libobjcの関数群 id objc_getClass(const char *name) nameクラスのClassを得る NSClassFromStringでも可 void method_exchangeImplementations(Method m1, Method m2) Methodの実装を置換する
  • 72. 例: 既存クラスのインスタンスメソッド同士を置換 void SwizzleInstanceMethod (Class cls, SEL old, SEL new) { Method mold = class_getInstanceMethod(cls, old); Method mnew = class_getInstanceMethod(cls, new); if (mold && mnew) method_exchangeImplementations(mold, mnew); }
  • 73. 実際の使い方 カテゴリを使って対象クラスにメソッドを追加し、 swizzlingする 元のメソッドを呼び出す場合は自分自身を呼び出 す事で実現 実装が入れ替わっているため
  • 74. 乗っ取り用メソッド実装例 @implementation NSObject (BlackDock) - (void)BlackDock_DOCKTrashTile_open { [self BlackDock_DOCKTrashTile_open]; [self someEventHook]; } @end
  • 75. 乗っ取り例 @implementation BlackDock + (void)load { Class cls = NSClassFromString(@"DOCKTrashTile"); SEL old = @selector(open); SEL new = @selector(BlackDock_DOCKTrashTile_open); SwizzleInstanceMethod(cls, old, new); } @end
  • 76. 例の解説 DOCKTrashTileというクラスのopenを BlackDock_DOCKTrashTile_openで置換 openの元の実装の挙動を優先する 乗っ取るメソッドは@selectorで指定
  • 77. 本日使う技術 アプリに侵入しよう! アプリを理解しよう! アプリを乗っ取ろう! アプリを操作しよう!
  • 78. ヘッダーを再配布したら怒られない?
  • 79. 無理矢理呼び出しましょう あると分かっているならリフレクション使えば良 いよね メンバ変数を呼ぶ時: class_getInstanceVariable メンバメソッドを呼ぶ: NSInvocation
  • 80. 変数読み出し Ivar class_getInstanceVariable(Class cls,
 const char* name) クラスの表現clsからnameの変数を取り出す id object_getIvar(id object, Ivar ivar) objectから表現ivarに対応する変数の値を得る
  • 81. 例(あるオブジェクトからメンバ変数を取り出す) Ivar getInstanceVariable(id obj, const char *name, void **value) { Ivar ivar; if ((ivar = class_getInstanceVariable(object_getClass(obj), name))) { if (value) *value = (__bridge void *)object_getIvar(obj, ivar); return ivar; } }
  • 82. メソッド呼び出し メッセージの識別子としての表現: @selector(hoge:) 方法1 NSInvocation: 静的にメッセージ呼び出しを実現する プロキシクラス 方法2 NSObjectの-performSelector:を使う
  • 83. NSProxy - (NSMethodSignature *) methodSignatureForSelector:(SEL)aSelector あるオブジェクトのメソッドを表すシグニチャ NSInvocation + (NSInvocation *)invocationWithMethodSignature: (NSMethodSignature *)signature シグニチャに対して実際に値を適用する
  • 84. void invoke(id target, SEL selector, void *arg1, void *ret){ NSMethodSignature *sig = [target methodSignatureForSelector:selector]; NSInvocation* inv = [NSInvocation invocationWithMethodSignature:sig]; [inv setSelector:selector]; // メッセージを [inv setTarget:target]; // どのオブジェクトに対して [inv setArgument:arg1 atIndex:2]; // 第1引数をarg1として [inv invoke]; // 呼び出す [inv getReturnValue:ret]; // 返り値をポインタに代入 }
  • 85. もう少し楽に え?面倒くさい? 引数無くても書かなきゃならんのか NSObject - (id)performSelector:(SEL)aSelector aSelectorは単項メッセージ限定
  • 86. 例 [spaces performSelector:@selector(displays)] 同じ例 invoke(spaces, @selector(displays), NULL, NULL);
  • 87. 本日話す事 コレがしたい 前提のお話 今回必要となる技術 実際にアプリを見てみよう
  • 88. 本日のテーマ Dock.app
  • 89. サンプルアプリ 作ったもの見せたかったけど時間無いしね サンプルアプリ「BlackDock.app」 ゴミ箱をクリックしたらDockがかっこ良くなる
  • 90. 仕組み 1. ゴミ箱のクリックのイベントを監視する 2. Dockのベースを形作るビューを取得する 3. 自力で書いたレイヤーで置き換える
  • 91. だします

×