Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
ヘッダ参照の『鶏と卵』問題
Masayuki Nii
2010/10/25
iOS Developer勉強会.Urawa #2

1
Agenda

コンパイルにはヘッダのインクルードが必要
他のクラスを使う場合は通常はヘッダのインクルードが
必要になる
プレフィックスヘッダを使えばよりシンプルに書ける
[おまけ]メンバ変数やメソッドの隠匿化
[おまけ]バージョンによる分岐
...
ヘッダとソース
MyAppDelegate.h
@interface MyAppDelegate : NSObject {
}
@end

MyAppDelegate.m
#import “MyAppDelegate”
@implementat...
他のクラスを参照する場合
MyAppDelegate.h
@interface MyAppDelegate : NSObject {
UIWindow *window;
MyAppListViewController *listView;
My...
他のヘッダやクラスの定義を追加する
MyAppDelegate.h
@class MyAppListViewController;
@class MyAppDetailViewController;
@interface MyAppDelega...
ヘッダファイルの存在

結果的にすべての.mファイルで他のヘッダを読み込むこ
とになる

•
•

通常は「全部」は不要だが、後から追加するときに必ずヘッダを指
定することになる
ヘッダには@classでクラス名を追加する

1クラスを1ヘッダ...
プレフィックスヘッダの利用
コンパイル時に必ず読み込
むヘッダ

•
•
•

通常はフレームワークのヘッダ
のみが指定されている
すべてのソースのコンパイル時
に読み込まれる
拡張子は.pch

Xcodeではプリコンパイル
や共有が可能

...
プリコンパイルヘッダに定義を集める
MyAppDelegate.h
@interface MyAppDelegate : NSObject {
UIWindow *window;
MyAppListViewController *listVie...
プリコンパイルヘッダ
あらかじめコンパイルしたヘッダ

•
•

たくさんのヘッダがあった時代の産物
ほんとうに何分、何十分とかかる時代があった

iOS時代、ヘッダは減った

•
•

プリコンパイルがすぐ(1秒くらい?)で終わる
ヘッダを全...
余談:importとinclude

include

•
•
•
•

ファイルを読み込むプリプロセッサ
C言語で定義
2重の読み込みがなされる可能性があり、#ifndef等で排除
ヘッダパスをコンパイル時に指定するのが一般的なので、ソース上...
Objective-Cのスコープ
メンバ変数

•
•
•

@public、@privateでスコープを定義できる
プロパティを使う方がスマートかつ安全
つまり、全部@privateにし、外部からアクセス可能なメンバ変数に
したい場合は、プロ...
プライベートなメソッドの定義
MyAppDetailViewController.h
@interface MyAppDetailViewController : NSViewController {
@private
UIScrollView...
メリット

クラス内で使うメソッドの定義が楽

•

.mファイルの修正だけでOK

スコープをコントロール

•

.hファイルには外部から利用したいメソッドだけの定義でかまわな
いので、メソッドが入り乱れない

13
one more Omake...

SDKのバージョンによるコンパイルの分岐

•
•
•

Ver.3とVer.4で異なる場合の処理が面倒になってきた
ex. NSConnectionDelegate、Blocksなど
Availabili...
まとめ

プレフィックスヘッダを積極的に使おう
プライベートメソッドを意識しよう

15
Upcoming SlideShare
Loading in …5
×

iOS.Dev.Urawa#2-ヘッダ参照の『鶏と卵』問題

645 views

Published on

iOS.Dev.Urawa#2
2010/10/25
ヘッダ参照の『鶏と卵』問題
新居雅行

Published in: Technology
  • Be the first to comment

iOS.Dev.Urawa#2-ヘッダ参照の『鶏と卵』問題

  1. 1. ヘッダ参照の『鶏と卵』問題 Masayuki Nii 2010/10/25 iOS Developer勉強会.Urawa #2 1
  2. 2. Agenda コンパイルにはヘッダのインクルードが必要 他のクラスを使う場合は通常はヘッダのインクルードが 必要になる プレフィックスヘッダを使えばよりシンプルに書ける [おまけ]メンバ変数やメソッドの隠匿化 [おまけ]バージョンによる分岐 2
  3. 3. ヘッダとソース MyAppDelegate.h @interface MyAppDelegate : NSObject { } @end MyAppDelegate.m #import “MyAppDelegate” @implementation MyAppDelegate @end MyAppListViewController.h @interface MyAppListViewController : NSViewController { } @end MyAppListViewController.m #import “MyAppListViewController” @implementation MyAppListViewController @end MyAppDetailViewController.h @interface MyAppDetailViewController : NSViewController { } @end MyAppDetailViewController.m #import “MyAppDetailViewController” @implementation MyAppDetailViewController @end 3
  4. 4. 他のクラスを参照する場合 MyAppDelegate.h @interface MyAppDelegate : NSObject { UIWindow *window; MyAppListViewController *listView; MyAppDetailViewController *detailView; } @end MyAppDelegate.m MyAppListViewController.h MyAppListViewController.m @interface MyAppListViewController : NSViewController { } @end #import “MyAppListViewController” @implementation MyAppListViewController @end MyAppDetailViewController.h @interface MyAppDetailViewController : NSViewController { } @end MyAppDetailViewController.m #import “MyAppDetailViewController” @implementation MyAppDetailViewController @end #import “MyAppDelegate” @implementation MyAppDelegate @end エラーになるはず! 4
  5. 5. 他のヘッダやクラスの定義を追加する MyAppDelegate.h @class MyAppListViewController; @class MyAppDetailViewController; @interface MyAppDelegate : NSObject { UIWindow *window; MyAppListViewController *listView; MyAppDetailViewController *detailView; } @end MyAppListViewController.h @interface MyAppListViewController : NSViewController { } @end MyAppDetailViewController.h @interface MyAppDetailViewController : NSViewController { } @end MyAppDelegate.m #import “MyAppDelegate” #import “MyAppListViewController” #import “MyAppDetailViewController” @implementation MyAppDelegate @end MyAppListViewController.m #import “MyAppListViewController” #import “MyAppDelegate” #import “MyAppDetailViewController” @implementation MyAppListViewController UIApplication ap = [UIApplication sharedApplication]; MyAppDelegate *aDel = ap.delegate; MyAppDetailViewController *dvc = aDel.detailView; @end MyAppDetailViewController.m #import “MyAppDetailViewController” @implementation MyAppDetailViewController @end 5
  6. 6. ヘッダファイルの存在 結果的にすべての.mファイルで他のヘッダを読み込むこ とになる • • 通常は「全部」は不要だが、後から追加するときに必ずヘッダを指 定することになる ヘッダには@classでクラス名を追加する 1クラスを1ヘッダで作る限りはその必要がある 6
  7. 7. プレフィックスヘッダの利用 コンパイル時に必ず読み込 むヘッダ • • • 通常はフレームワークのヘッダ のみが指定されている すべてのソースのコンパイル時 に読み込まれる 拡張子は.pch Xcodeではプリコンパイル や共有が可能 • 開発中に変更がほとんどない ようなヘッダ群をコンパイルし た状態にしておく 7
  8. 8. プリコンパイルヘッダに定義を集める MyAppDelegate.h @interface MyAppDelegate : NSObject { UIWindow *window; MyAppListViewController *listView; MyAppDetailViewController *detailView; } @end MyAppDelegate.m @implementation MyAppDelegate @end MyAppListViewController.h @interface MyAppListViewController : NSViewController { } @end MyAppDetailViewController.h @interface MyAppDetailViewController : NSViewController { } @end MyApp.pch @class MyAppDelegate; @class MyAppListViewController; @class MyAppDetailViewController; #import <UIKit/UIKit.h> #import “MyAppDelegate” #import “MyAppListViewController” #import “MyAppDetailViewController” MyAppListViewController.m @implementation MyAppListViewController UIApplication ap = [UIApplication sharedApplication]; MyAppDelegate *aDel = ap.delegate; MyAppDetailViewController *dvc = aDel.detailView; @end MyAppDetailViewController.m @implementation MyAppDetailViewController @end 8
  9. 9. プリコンパイルヘッダ あらかじめコンパイルしたヘッダ • • たくさんのヘッダがあった時代の産物 ほんとうに何分、何十分とかかる時代があった iOS時代、ヘッダは減った • • プリコンパイルがすぐ(1秒くらい?)で終わる ヘッダを全部入れておけば、.h/.mファイルでの参照は不要 注意点 • • 継承したクラスがある場合、プリコンパイルヘッダでの順序に依存 する Google DOMクラスのようにプリコンパイルヘッダに入れておくと エラーになるような場合もある。これについては通常通りの使用方 法にする 9
  10. 10. 余談:importとinclude include • • • • ファイルを読み込むプリプロセッサ C言語で定義 2重の読み込みがなされる可能性があり、#ifndef等で排除 ヘッダパスをコンパイル時に指定するのが一般的なので、ソース上 では相対的なパスを記述する import • • Objective-Cで追加されたプリプロセッサ 同じファイルを2度読みしないようになっている 10
  11. 11. Objective-Cのスコープ メンバ変数 • • • @public、@privateでスコープを定義できる プロパティを使う方がスマートかつ安全 つまり、全部@privateにし、外部からアクセス可能なメンバ変数に したい場合は、プロパティを使うのがいい メソッド • • Objective-Cにはスコープの概念がない しかしやりようはある 萩原先生の書籍 Objective-C 2.0(p229) 最近の生成ソースやサンプル Technique to make some methods to "private" http://stackoverflow.com/questions/172598/best-way-todefine-private-methods-for-a-class-in-objective-c • • • 11
  12. 12. プライベートなメソッドの定義 MyAppDetailViewController.h @interface MyAppDetailViewController : NSViewController { @private UIScrollView *myScroll; UIView *myContents; } @property (retain, nonatmic) IBOutlet UIScrollView *myScroll; @property (retain, nonatmic) IBOutlet UIView *myContents; -(void) setupContents: (NSString *)param; @end MyAppDetailViewController.m @interface MyAppDetailViewController() -(NSArray *)analyzeParameter:(NSString *)p; @end ←カテゴリの定義 ←プライベートメソッド @implementation MyAppDetailViewController -(void) setupContents: (NSString *)param {} -(NSArray *)analyzeParameter:(NSString *)p {} @end 12
  13. 13. メリット クラス内で使うメソッドの定義が楽 • .mファイルの修正だけでOK スコープをコントロール • .hファイルには外部から利用したいメソッドだけの定義でかまわな いので、メソッドが入り乱れない 13
  14. 14. one more Omake... SDKのバージョンによるコンパイルの分岐 • • • Ver.3とVer.4で異なる場合の処理が面倒になってきた ex. NSConnectionDelegate、Blocksなど Availability.h等に関連キーワードが定義されている #if __IPHONE_OS_VERSION_MIN_REQUIRED > 30200 .... ↑ #else SDK Ver.3.2を .... #endif 意味する 14
  15. 15. まとめ プレフィックスヘッダを積極的に使おう プライベートメソッドを意識しよう 15

×