+ All Categories
Home > Technology > Cocoa Pro5

Cocoa Pro5

Date post: 28-Jun-2015
Category:
Upload: hasegawa
View: 970 times
Download: 0 times
Share this document with a friend
Popular Tags:
78
iPhone輪講 Lesson10/Lesson11 乗るしかないこのビッグウエーブ第5回
Transcript
Page 1: Cocoa Pro5

iPhone輪講Lesson10/Lesson11

乗るしかないこのビッグウエーブに

第5回

Page 2: Cocoa Pro5

Lesson10Objective-Cの文法

Page 3: Cocoa Pro5

クラスの宣言と実装

クラスの記述は2つの部分からなるクラスの宣言

クラスがどういったインスタンス変数を持っているか,どういったメソッドを持っているかということを定義するする部分

クラスの実装

宣言したメソッドの定義を書く部分

Page 4: Cocoa Pro5

クラスの宣言と実装

クラスの宣言と実装のファイルにはそれぞれ拡張子があるクラス宣言には「.h」という拡張子をつける

hはヘッダ(header)の意味

クラス実装には「.m」という拡張子をつける

mはメソッド(method)の意味

Page 5: Cocoa Pro5

文法実験の仕方

以前作ったObjective-CのテストのためのプロジェクトObjC Testをひらくソースコードは3つのファイルに書かれていた

クラス宣言のためのファイルはMyObject.h

クラス実装のためのファイルはMyObject.m

クラスをインスタンス化してメソッドを呼び起こすのがObjC Test.m

Page 6: Cocoa Pro5

文法実験の仕方

ObjC Test.mのソースコードを見返してみる

Page 7: Cocoa Pro5

文法実験の仕方

ObjC Test.mのソースコードを見返してみる

Page 8: Cocoa Pro5

文法実験の仕方

ObjC Test.mのソースコードを見返してみるNSAutoreleasePoolというクラスのインスタンス化を行っている

Page 9: Cocoa Pro5

文法実験の仕方

ObjC Test.mのソースコードを見返してみる

Page 10: Cocoa Pro5

文法実験の仕方

ObjC Test.mのソースコードを見返してみる

Page 11: Cocoa Pro5

文法実験の仕方

ObjC Test.mのソースコードを見返してみる

Page 12: Cocoa Pro5

文法実験の仕方

ObjC Test.mのソースコードを見返してみる

MyObjectクラスのインスタンス化をしている

Page 13: Cocoa Pro5

クラスの宣言

クラス宣言の読み込みクラスは親クラスを継承してサブクラスを作る

ソースコードを読み込んで処理するのはコンパイラ

コンパイラが親クラスの事を知らなくてはいけない

コンパイルするとき,親クラスの宣言を読み込んでおく

Page 14: Cocoa Pro5

フレームワークのクラス宣言の読み込み

読み込むために使うのが「#import」という文Cocoaのクラス宣言ファイルを読み込むには,以下のように書く

これは「システムにある,Cocoaフレームワークの,Cocoa.hというファイルを読み込む」という意味

#importの後の< >が,システムのヘッダファイルを意味する

Page 15: Cocoa Pro5

フレームワークのクラス宣言の読み込み

#import <Cocoa/Cocoa.h>の指示で読み込むファイル/システム/ライブラリ/Frameworks/Cocoa.framework/Headers/Cocoa.h

Foundation,AppKit,CoreDataというフレームワークのヘッダファイルを読み込んでいる

Page 16: Cocoa Pro5

自分で作ったクラス宣言の読み込み

自分で作ったクラス宣言ファイル(Tigers.h)を読む場合は以下のように書く

#importの後にダブルクォーテーション(“ “)が来ている

これはヘッダファイルがプロジェクト内部にある事を示す

Page 17: Cocoa Pro5

クラスの宣言

クラスの宣言をするまず名前を決める(今回はMyObject)

親クラスを決める

何かのクラスを拡張するときは,そのクラスを書く

何も無い場合はCocoaのルートクラスのNSObjectを使う

クラス宣言の宣言 クラス名 親クラスの名前

Page 18: Cocoa Pro5

インスタンス変数の宣言

クラスの宣言にインスタンス変数の宣言を加える事ができる

@interfaceと@endの間に「{ }」を加えて,その中に書く

Page 19: Cocoa Pro5

メソッドの宣言

引数なしのインスタンスメソッドインスタンス変数であるcountの値を取得するためのメソッドを宣言する

文法は  - (返り値型)メソッド名;

Page 20: Cocoa Pro5

メソッドの宣言

引数1つのインスタンスメソッドcountの値を設定するためのメソッド

文法は - (返り値型)メソッド名:(引数型)引数名;

Page 21: Cocoa Pro5

メソッドの宣言

引数2つ以上のインスタンスメソッドcountとindexの値を同時に設定する

文法は - (返り値型)メソッド名:(引数名)引数名 ラベル:(引数型)引数名;

Page 22: Cocoa Pro5

メソッドの宣言

クラスメソッドメソッドにはクラスメソッドもある

インスタンスメソッドの宣言は「 - 」から始まっていたが,クラスメソッドの宣言は「 + 」から始まる

それ以外はインスタンスメソッドと同じ

Page 23: Cocoa Pro5

クラスの実装

クラスの実装を書いてみるクラスの実装には@implementationを使う

@implementationの後ろにはクラス名が来る

Page 24: Cocoa Pro5

メソッドの実装

MyObjectにメソッドの実装を付け加える

メソッドの実装は@implementationと@endの間に書く

宣言と同じ形でメソッドを書き,中括弧({ })の中にメソッドでの処理を実装していく

Page 25: Cocoa Pro5

メソッドの宣言は常に必要か?

ここまでだと「.hでメソッド宣言」→「.mでメソッド実装」という流れメソッドの宣言は常に必要なのか?

Objective-Cでは,メソッドの宣言をせずに,いきなり実装しても構わない

他のクラスから呼んでもらう必要の無いものは.hファイルに加えなくてよい

Page 26: Cocoa Pro5

オブジェクトのための変数型

Objective-CはC言語ベースなので,基本的な変数の型はC言語と同じchar,int,floatといった型はそのまま使える

それらに加えて,Objective-Cのための変数も追加されている

それがオブジェクトのための変数型

Page 27: Cocoa Pro5

インスタンスオブジェクトのための変数型

インスタンスオブジェクトのための変数クラスをインスタンス化するとオブジェクトができる

このオブジェクトに入れるための変数

Page 28: Cocoa Pro5

インスタンスオブジェクトのための変数型

変数は「クラス名のポインタ」という形式の型になるMyObjectクラスのインスタンスのための変数

CocoaのクラスであるNSStringのための変数

Page 29: Cocoa Pro5

id型

オブジェクトの変数のための型にはid型という特殊なものが用意されているid型はすべてのオブジェクトのために使える型

CocoaのすべてのクラスはNSObjectから継承されている

このNSObjectにはObjective-Cのすべてのオブジェクトに共通するデータが含まれている

これを表すための変数型がid型

Page 30: Cocoa Pro5

id型

すべてのオブジェクトはid型の変数に代入することができるそれだと,その変数が何のクラスだったのかわかりにくい

それを避けたいときはクラス名のポインタ型を使うことになる

Page 31: Cocoa Pro5

id型

以前作ったHello WorldアプリケーションのAppController.hを開くクラスの宣言でid型が使われていた

何のクラスかわかりやすく書き換える

Page 32: Cocoa Pro5

nil値

C言語ではポインタが何も指してない状態を表すためにNULLという値があったObjective-Cにもオブジェクトのための変数が,何のオブジェクトも指し示していないことを表すnilという値がある

これでstringという変数は何も指し示していないという事が保証される

Page 33: Cocoa Pro5

メソッドの呼び出し

インスタンスメソッドの呼び出しMyObjectクラスにcountというクラスを実装した

これを呼び出してみる

インスタンスメソッドを呼び出すには,あらかじめインスタンス化しておかなければならない →Lesson12

Page 34: Cocoa Pro5

メソッドの呼び出し

インスタンスメソッドの呼び出しインスタンス化されたオブジェクトに対して,メソッドを呼び出しているのが「count = [object count];」

文法は 返り値 = [インスタンス メソッド名];

メソッドは関数と同じように返り値を返す.

角括弧の中にインスタンスオブジェクト,空白をあけてメソッド名を書く

これがメソッドの呼び出し

Page 35: Cocoa Pro5

クラスメソッドの呼び出し

クラスメソッドの呼び出し文法自体はインスタンスメソッドのものと変わらない

違いは呼び出しの対象となるオブジェクト

インスタンスメソッドのときは,インスタンス化したオブジェクトを使った

クラスメソッドは,クラス全体に対して呼び出す

呼び出す対象のところにクラス名を指定する

Page 36: Cocoa Pro5

オブジェクトがnilの場合

インスタンスメソッドの呼び出しのとき,インスタンスのオブジェクトのための変数を使っていた普通にインスタンス化されたオブジェクトを指していれば問題無し

nilが入っていた場合どうなるか

nilに対してメソッドを呼び出すと,その呼び出しは無視される

返り値は型に関わらず0が返ってくる

Page 37: Cocoa Pro5

Lesson11チュートリアル:RSSリーダ

Page 38: Cocoa Pro5

開発の手順

1. 新規プロジェクトの作成をするCocoa Applicationテンプレートを使う

2. アプリケーションのためのクラスを作成をするMVCアーキテクチャに則って,コントローラを1つ作る

アウトレットとアクションも追加しておく

Page 39: Cocoa Pro5

開発の手順

3. Interface Builderでユーザインタフェースのデザインをするインタフェースの部品に様々な設定を施す

4. アウトレットとアクションを接続するアウトレットはコントロールクラスから,アクションはボタンとテキストフィールドから接続する

テーブルビューでは特殊な設定が必要となる

Page 40: Cocoa Pro5

開発の手順

5. ソースコードを書く

6. ビルドしてから実行する

Page 41: Cocoa Pro5

プロジェクトの作成

プロジェクトを作成する[ファイル]→[新規プロジェクト...]メニューを開く

「Cocoa Application」を選択する

プロジェクト名は「RSS Reader」にして適当な場所に保存

Page 42: Cocoa Pro5

プロジェクトの作成

ガベージコレクションの設定プロジェクトウィンドウのターゲットの項目を開く

「RSS Reader」という名前のターゲットがあるのでダブルクリック

「ターゲット”RSS Reader”の情報」というウィンドウが開く

Page 43: Cocoa Pro5

プロジェクトの作成

ガベージコレクションの設定

「ターゲット”RSS Reader”の情報」のウィンドウにはタブがあるので「ビルド」のタブを選択

ビルドの設定を行う画面になる

構成のメニューは「すべての構成」,表示のメニューは「すべての設定」にしておく

Page 44: Cocoa Pro5

プロジェクトの作成

ガベージコレクションの設定

「GCC 4.0 - Code Generation」のカテゴリの中にある「Objective-C Garbage Collection」の設定を変更する

ガーベッジコレクションの設定では「Unsupported」「Supported」「Required」という値を指定できる

ここでは「Required」を指定する

Page 45: Cocoa Pro5

クラスの作成

クラスを作成するアプリケーションのためのコントローラクラスを作る

[ファイル]→[新規ファイル...]メニューを選択する

テンプレート一覧から「Objective-C class」を選択する

ファイル名を「AppController」とする

Page 46: Cocoa Pro5

クラスの作成

AppController.hを編集する

Page 47: Cocoa Pro5

ユーザインタフェースのデザイン

部品の配置プロジェクトウィンドウでMainMenu.xibを開く

Interface Builderが起動するのでそちらで作業する

アプリケーションのメインウィンドウが開いているので,その上に部品を配置していく

Page 48: Cocoa Pro5

ユーザインタフェースのデザイン

部品の配置今回使う部品は4種類

1.編集可能なテキストフィールド

2.編集不可能なテキストフィールド

3.ボタン

4.テーブルビュー

Page 49: Cocoa Pro5

ユーザインタフェースのデザイン

部品の配置部品はライブラリの[Cocoa]→[Views&Cells]の下にある

テキストフィールドは[Inputs&Values]

ボタンは[Buttons]

テーブルビューは[Data Views]

Page 50: Cocoa Pro5

ユーザインタフェースのデザイン

ユーザインタフェースをデザインするウィンドウ上に部品を配置していく(全部で8ヶ所)

① ② ③ ① ①①

④ ⑤⑥ ⑦

Page 51: Cocoa Pro5

ユーザインタフェースのデザイン

テキストフィールドの設定編集可能なテキストフィールドを選択する

インスペクタパネルのAttributesタブの「Action」と書かれているポップアップメニューから「Set On Enter Only」を選択する

Enterキーを押したときにだけアクションが送られるようになる

Page 52: Cocoa Pro5

ユーザインタフェースのデザイン

テキストフィールドの設定編集可能なテキストフィールドを選択する

インスペクタパネルのAttributesタブの「Action」と書かれているポップアップメニューから「Set On Enter Only」を選択する

Enterキーを押したときにだけアクションが送られるようになる

Page 53: Cocoa Pro5

ユーザインタフェースのデザイン

テキストフィールドの設定編集可能なテキストフィールドを選択する

インスペクタパネルのAttributesタブの「Action」と書かれているポップアップメニューから「Set On Enter Only」を選択する

Enterキーを押したときにだけアクションが送られるようになる

Page 54: Cocoa Pro5

ユーザインタフェースのデザイン

テーブルビューの設定テーブルビューをクリックする

インスペクタのタイトルバーに「Scroll View」と表示されていれば,テーブルビューの外側に位置するスクロールビューを選択していることになる

Page 55: Cocoa Pro5

ユーザインタフェースのデザイン

テーブルビューの設定

スクロールビューが選択されている状態で設定を行う

横スクロールバーを表示しないようにする

インスペクタのAttributesタブにある「Show Horizontal Scroller」のチェックを外す

Page 56: Cocoa Pro5

ユーザインタフェースのデザイン

テーブルビューの設定Scroll Viewの状態でテーブルをもう一度クリックする

インスペクタのタイトルが「Table View」になる

スクロールビュー内部のテーブルビューが選択できている事を示している

Page 57: Cocoa Pro5

ユーザインタフェースのデザイン

テーブルビューの設定

「Col. Sizing」というポップアップメニューから「Uniform」を選択する

これでテーブルビューの大きさを変更したとき,列サイズも均等に変わる事になる

Page 58: Cocoa Pro5

ユーザインタフェースのデザイン

テーブルビューの設定テーブルのヘッダ部分をクリックする

タイトルが「Table Header View」となる

さらにクリックして,ヘッダのみが白く強調され他がグレーアウトになるようにする

この状態で列の境目をドラッグして,列の大きさが調整できる

Page 59: Cocoa Pro5

ユーザインタフェースのデザイン

テーブルビューの設定ヘッダをダブルクリックする事で 列にタイトルを設定できる

左側に「Title」右側に「Link」を入力する

Page 60: Cocoa Pro5

ユーザインタフェースのデザイン

テーブルビューの設定列の識別子を設定する

「Table Column」と呼ばれる項目を選択する必要がある

再び「Table View」を選択した状態にする

この状態でテーブルビューの左側の領域をクリック

左側だけが強調されて,インスペクタのタイトルが「Table Column」となる

Page 61: Cocoa Pro5

ユーザインタフェースのデザイン

テーブルビューの設定

識別子の設定をする

インスペクタに「Identifier」という項目がある

Title列は「title」,Link列には「link」と入力する

「Editable」のチェックをそれぞれ外す

Page 62: Cocoa Pro5

自動リサイズの設定

自動リサイズの設定をするURLテキストフィールドの設定をおこなう

「URL:」と書いてあるテキストフィールドを選択してインスペクタのSizeタブも表示する

このテキストフィールドは左上に固定する

Autosizingの設定で外側の左と上の設定をする

Page 63: Cocoa Pro5

自動リサイズの設定

同様にすべての部品を設定する「Title:」,「Link:」のテキストフィールドは左上固定

編集可能なテキストフィールド,「title」,「link」のテキストフィールドは上に固定で横方向にはリサイズ

「Read」ボタンは右上固定

テーブルビューはスクロールビューの中に入れられている

リサイズの設定は外側のスクロールビューに対しておこなう

Page 64: Cocoa Pro5

自動リサイズの設定

Page 65: Cocoa Pro5

ウィンドウの設定

ウィンドウのタイトルを設定するウィンドウを選択して,インスペクタのAttributesのタブを表示する

「Title」というテキストフィールドに,「RSS Reader」と入力する

Page 66: Cocoa Pro5

クラスのインスタンス化

クラスをインスタンス化するライブラリの[Cocoa] > [Objects&Controller] > [Controllers]にあるObjectをxibウィンドウにドラッグして追加

オブジェクトを選択したままインスペクタを表示し,Identityタブで「AppController」クラスを選択する

Page 67: Cocoa Pro5

アウトレットとアクションの接続

テキストフィールドのアウトレットを接続する

「urlTextField」,「titleTextField」,「linkTextField」をコントロールキーを押しながらそれぞれ接続する

urlTextFieldtitleTextField

linkTextField

Page 68: Cocoa Pro5

アウトレットとアクションの接続

アクションの接続をする

「Read」ボタンから,「readURL;」アクションに接続する

入力可能なテキストフィールドからも「readURL ;」アクションに接続する

このアクションはテキストフィールドで Enterキーを押したときに送られる

readURL; readURL;

Page 69: Cocoa Pro5

アウトレットとアクションの接続

テーブルビューのアウトレットを接続する

コントロールをしながらテーブルビューをクリックし,AppControllerまでドラッグして,上でドロップする

テーブルビューアウトレットの中から「dataSource」を選択

dataSource

Page 70: Cocoa Pro5

AppControllerクラスの実装

AppController.mを編集するソースコードの内容は次のスライドから…

Page 71: Cocoa Pro5

#import "AppController.h"

@implementation AppController

- (IBAction)readURL:(id)sender{ NSURL* url; url = [NSURL URLWithString:[urlTextField stringValue]]; // XMLドキュメントを作成します document = [[NSXMLDocument alloc] initWithContentsOfURL:url options:0 error:NULL]; if (!document) { return; } // '/rss/channle/title'のノードを取得します NSArray* nodes; nodes = [document nodesForXPath:@"/rss/channel/title" error:NULL]; if ([nodes count] == 0) { // '/rdf:RDF/channel/title'のノードを取得します nodes = [document nodesForXPath:@"/rdf:RDF/channel/title" error:NULL]; } if ([nodes count] == 0) { // '/feed/title'のノードを取得します nodes = [document nodesForXPath:@"/feed/title" error:NULL]; }

Page 72: Cocoa Pro5

if ([nodes count] == 1) { NSXMLNode* titleNode; titleNode = [nodes objectAtIndex:0]; // テキストフィールドにタイトルを設定します NSString* title; title = [titleNode stringValue]; [titleTextField setStringValue:title]; } // '/rss/channle/link'のノードを取得します nodes = [document nodesForXPath:@"/rss/channel/link" error:NULL]; if ([nodes count] == 0) { // '/rdf:RDF/channel/link'のノードを取得します nodes = [document nodesForXPath:@"/rdf:RDF/channel/link" error:NULL]; } if ([nodes count] == 0) { // '/feed/link'のノードを取得します nodes = [document nodesForXPath:@"/feed/link" error:NULL]; }

Page 73: Cocoa Pro5

if ([nodes count] == 1) { NSXMLNode* linkNode; linkNode = [nodes objectAtIndex:0]; // テキストフィールドにリンクを設定します NSString* link; link = [linkNode stringValue]; [linkTextField setStringValue:link]; } // テーブルビューにデータを読み込みます [tableView reloadData];}

// NSTableViewデータソース- (int)numberOfRowsInTableView:(NSTableView*)tableView{ if (!document) { return 0; }

Page 74: Cocoa Pro5

// '/rss/channel/item/'のノードを取得します NSArray* nodes; nodes = [document nodesForXPath:@"/rss/channel/item" error:NULL]; if ([nodes count] == 0) { // '/rdf:RDF/item'のノードを取得します nodes = [document nodesForXPath:@"/rdf:RDF/item" error:NULL]; } if ([nodes count] == 0) { // '/feed/entry'のノードを取得します nodes = [document nodesForXPath:@"/feed/entry" error:NULL]; } // ノードの数を返します return [nodes count];}

Page 75: Cocoa Pro5

// NSTableViewデータソース- (id)tableView:(NSTableView*)tableView objectValueForTableColumn:(NSTableColumn*)tableColumn row:(int)row{ if (!document) { return nil; } // テーブルカラムの識別子を取得します id identifier; identifier = [tableColumn identifier]; // '/rss/channel/item/'のノードを取得します NSArray* nodes; nodes = [document nodesForXPath:@"/rss/channel/item" error:NULL]; if ([nodes count] == 0) { // '/rdf:RDF/item'のノードを取得します nodes = [document nodesForXPath:@"/rdf:RDF/item" error:NULL]; } if ([nodes count] == 0) { // '/feed/entry'のノードを取得します nodes = [document nodesForXPath:@"/feed/entry" error:NULL]; }

Page 76: Cocoa Pro5

// 指定された行の、ノードを取得します NSXMLNode* node; node = [nodes objectAtIndex:row]; if ([identifier isEqual:@"title"]) { // 'title'の文字列を取得します nodes = [node nodesForXPath:@"title" error:NULL]; if ([nodes count] == 1) { node = [nodes objectAtIndex:0]; return [node stringValue]; } } if ([identifier isEqual:@"link"]) { // 'link'の文字列を取得します nodes = [node nodesForXPath:@"link" error:NULL]; if ([nodes count] == 1) { node = [nodes objectAtIndex:0]; return [node stringValue]; } } return nil;}

@end

Page 77: Cocoa Pro5

ビルドと実行

ビルドして実行する

[ビルド]→[ビルドと実行]メニューを選択する

RSS Readerのアプリケーションが起動する

Page 78: Cocoa Pro5

おわり


Recommended