Cocoa Pro5

1,110 views

Published on

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

  • Be the first to like this

No Downloads
Views
Total views
1,110
On SlideShare
0
From Embeds
0
Number of Embeds
30
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Cocoa Pro5

  1. 1. 第5回iPhone輪講Lesson10/Lesson11 乗るしかないこのビッグウエーブに
  2. 2. Lesson10Objective-Cの文法
  3. 3. クラスの宣言と実装クラスの記述は2つの部分からなるクラスの宣言 クラスがどういったインスタンス変数を持っているか,どういっ たメソッドを持っているかということを定義するする部分クラスの実装 宣言したメソッドの定義を書く部分
  4. 4. クラスの宣言と実装クラスの宣言と実装のファイルにはそれぞれ拡張子があるクラス宣言には「.h」という拡張子をつける hはヘッダ(header)の意味クラス実装には「.m」という拡張子をつける mはメソッド(method)の意味
  5. 5. 文法実験の仕方以前作ったObjective-CのテストのためのプロジェクトObjC Testをひらくソースコードは3つのファイルに書かれていた クラス宣言のためのファイルはMyObject.h クラス実装のためのファイルはMyObject.m クラスをインスタンス化してメソッドを呼び起こすのが ObjC Test.m
  6. 6. 文法実験の仕方ObjC Test.mのソースコードを見返してみる
  7. 7. 文法実験の仕方ObjC Test.mのソースコードを見返してみる
  8. 8. 文法実験の仕方 NSAutoreleasePoolというクラスのObjC Test.mのソースコードを見返してみる インスタンス化を行っている
  9. 9. 文法実験の仕方ObjC Test.mのソースコードを見返してみる
  10. 10. 文法実験の仕方ObjC Test.mのソースコードを見返してみる
  11. 11. 文法実験の仕方ObjC Test.mのソースコードを見返してみる
  12. 12. 文法実験の仕方ObjC Test.mのソースコードを見返してみる MyObjectクラスの インスタンス化をしている
  13. 13. クラスの宣言クラス宣言の読み込みクラスは親クラスを継承してサブクラスを作るソースコードを読み込んで処理するのはコンパイラ コンパイラが親クラスの事を知らなくてはいけない コンパイルするとき,親クラスの宣言を読み込んでおく
  14. 14. フレームワークのクラス宣言の 読み込み読み込むために使うのが「#import」という文Cocoaのクラス宣言ファイルを読み込むには,以下のように書く これは「システムにある,Cocoaフレームワークの, Cocoa.hというファイルを読み込む」という意味 #importの後の< >が,システムのヘッダファイルを意味する
  15. 15. フレームワークのクラス宣言の 読み込み#import <Cocoa/Cocoa.h>の指示で読み込むファイル /システム/ライブラリ/Frameworks/Cocoa.framework/ Headers/Cocoa.h Foundation,AppKit,CoreDataというフレームワークのヘッダ ファイルを読み込んでいる
  16. 16. 自分で作ったクラス宣言の読み込み自分で作ったクラス宣言ファイル(Tigers.h)を読む場合は以下のように書く #importの後にダブルクォーテーション( )が来ている これはヘッダファイルがプロジェクト内部にある事を示す
  17. 17. クラスの宣言クラスの宣言をするまず名前を決める(今回はMyObject)親クラスを決める 何かのクラスを拡張するときは,そのクラスを書く 何も無い場合はCocoaのルートクラスのNSObjectを使う クラス宣言の宣言 クラス名 親クラスの名前
  18. 18. インスタンス変数の宣言クラスの宣言にインスタンス変数の宣言を加える事ができる@interfaceと@endの間に「{ }」を加えて,その中に書く
  19. 19. メソッドの宣言引数なしのインスタンスメソッドインスタンス変数であるcountの値を取得するためのメソッドを宣言する 文法は  - (返り値型)メソッド名;
  20. 20. メソッドの宣言引数1つのインスタンスメソッドcountの値を設定するためのメソッド文法は - (返り値型)メソッド名:(引数型)引数名;
  21. 21. メソッドの宣言引数2つ以上のインスタンスメソッドcountとindexの値を同時に設定する 文法は - (返り値型)メソッド名:(引数名)引数名 ラベル:(引数型)引数名;
  22. 22. メソッドの宣言クラスメソッドメソッドにはクラスメソッドもあるインスタンスメソッドの宣言は「 - 」から始まっていたが,クラスメソッドの宣言は「 + 」から始まる それ以外はインスタンスメソッドと同じ
  23. 23. クラスの実装クラスの実装を書いてみるクラスの実装には@implementationを使う @implementationの後ろにはクラス名が来る
  24. 24. メソッドの実装MyObjectにメソッドの実装を付け加えるメソッドの実装は@implementationと@endの間に書く宣言と同じ形でメソッドを書き,中括弧({ })の中にメソッドでの処理を実装していく
  25. 25. メソッドの宣言は常に必要か?ここまでだと「.hでメソッド宣言」→「.mでメソッド実装」という流れメソッドの宣言は常に必要なのか? Objective-Cでは,メソッドの宣言をせずに,いきなり実装して も構わない 他のクラスから呼んでもらう必要の無いものは .hファイルに加えなくてよい
  26. 26. オブジェクトのための変数型Objective-CはC言語ベースなので,基本的な変数の型はC言語と同じchar,int,floatといった型はそのまま使えるそれらに加えて,Objective-Cのための変数も追加されている それがオブジェクトのための変数型
  27. 27. インスタンスオブジェクトのための 変数型インスタンスオブジェクトのための変数 クラスをインスタンス化するとオブジェクトができる このオブジェクトに入れるための変数
  28. 28. インスタンスオブジェクトのための 変数型変数は「クラス名のポインタ」という形式の型になる MyObjectクラスのインスタンスのための変数 CocoaのクラスであるNSStringのための変数
  29. 29. id型オブジェクトの変数のための型にはid型という特殊なものが用意されているid型はすべてのオブジェクトのために使える型CocoaのすべてのクラスはNSObjectから継承されている このNSObjectにはObjective-Cのすべてのオブジェクトに共通 するデータが含まれている これを表すための変数型がid型
  30. 30. id型すべてのオブジェクトはid型の変数に代入することができるそれだと,その変数が何のクラスだったのかわかりにくい それを避けたいときはクラス名のポインタ型を使うことになる
  31. 31. id型以前作ったHello WorldアプリケーションのAppController.hを開くクラスの宣言でid型が使われていた 何のクラスかわかりやすく書き換える
  32. 32. nil値C言語ではポインタが何も指してない状態を表すためにNULLという値があったObjective-Cにもオブジェクトのための変数が,何のオブジェクトも指し示していないことを表すnilという値がある これでstringという変数は何も指し示していない という事が保証される
  33. 33. メソッドの呼び出しインスタンスメソッドの呼び出しMyObjectクラスにcountというクラスを実装した これを呼び出してみる インスタンスメソッドを呼び出すには,あらかじめ インスタンス化しておかなければならない →Lesson12
  34. 34. メソッドの呼び出しインスタンスメソッドの呼び出しインスタンス化されたオブジェクトに対して,メソッドを呼び出しているのが「count = [object count];」文法は 返り値 = [インスタンス メソッド名]; メソッドは関数と同じように返り値を返す. 角括弧の中にインスタンスオブジェクト,空白をあけてメソッド 名を書く これがメソッドの呼び出し
  35. 35. クラスメソッドの呼び出しクラスメソッドの呼び出し文法自体はインスタンスメソッドのものと変わらない違いは呼び出しの対象となるオブジェクト インスタンスメソッドのときは,インスタンス化したオブジェク トを使った クラスメソッドは,クラス全体に対して呼び出す 呼び出す対象のところにクラス名を指定する
  36. 36. オブジェクトがnilの場合インスタンスメソッドの呼び出しのとき,インスタンスのオブジェクトのための変数を使っていた普通にインスタンス化されたオブジェクトを指していれば問題無しnilが入っていた場合どうなるか nilに対してメソッドを呼び出すと,その呼び出しは無視される 返り値は型に関わらず0が返ってくる
  37. 37. Lesson11チュートリアル: RSSリーダ
  38. 38. 開発の手順1. 新規プロジェクトの作成をする Cocoa Applicationテンプレートを使う2. アプリケーションのためのクラスを作成をする MVCアーキテクチャに則って,コントローラを1つ作る アウトレットとアクションも追加しておく
  39. 39. 開発の手順3. Interface Builderでユーザインタフェースの デザインをする インタフェースの部品に様々な設定を施す4. アウトレットとアクションを接続する アウトレットはコントロールクラスから,アクションはボタンと テキストフィールドから接続する テーブルビューでは特殊な設定が必要となる
  40. 40. 開発の手順5. ソースコードを書く6. ビルドしてから実行する
  41. 41. プロジェクトの作成プロジェクトを作成する[ファイル]→[新規プロジェクト...]メニューを開く「Cocoa Application」を選択するプロジェクト名は「RSS Reader」にして適当な場所に保存
  42. 42. プロジェクトの作成ガベージコレクションの設定プロジェクトウィンドウのターゲットの項目を開く「RSS Reader」という名前のターゲットがあるのでダブルクリック 「ターゲット RSS Reader の情報」という ウィンドウが開く
  43. 43. プロジェクトの作成ガベージコレクションの設定 「ターゲット RSS Reader の情 報」のウィンドウにはタブがあるの で「ビルド」のタブを選択 ビルドの設定を行う画面になる 構成のメニューは「すべての 構成」,表示のメニューは 「すべての設定」にしておく
  44. 44. プロジェクトの作成ガベージコレクションの設定「GCC 4.0 - Code Generation」のカテゴリの中にある「Objective-CGarbage Collection」の設定を変更する ガーベッジコレクションの設定では 「Unsupported」「Supported」 「Required」という値を指定できる ここでは「Required」を指定する
  45. 45. クラスの作成クラスを作成するアプリケーションのためのコントローラクラスを作る [ファイル]→[新規ファイル...]メニューを選択する テンプレート一覧から「Objective-C class」を選択する ファイル名を「AppController」とする
  46. 46. クラスの作成AppController.hを編集する
  47. 47. ユーザインタフェースのデザイン部品の配置プロジェクトウィンドウでMainMenu.xibを開く Interface Builderが起動するのでそちらで作業するアプリケーションのメインウィンドウが開いているので,その上に部品を配置していく
  48. 48. ユーザインタフェースのデザイン部品の配置 今回使う部品は4種類 1.編集可能なテキストフィールド 2.編集不可能なテキストフィールド 3.ボタン 4.テーブルビュー
  49. 49. ユーザインタフェースのデザイン部品の配置部品はライブラリの[Cocoa]→[Views&Cells]の下にある テキストフィールドは[Inputs&Values] ボタンは[Buttons] テーブルビューは[Data Views]
  50. 50. ユーザインタフェースのデザインユーザインタフェースをデザインするウィンドウ上に部品を配置していく(全部で8ヶ所) ① ② ③ ① ① ④ ⑤ ⑥ ⑦ ⑧
  51. 51. ユーザインタフェースのデザインテキストフィールドの設定編集可能なテキストフィールドを選択する インスペクタパネルのAttributesタブの「Action」と 書かれているポップアップメニューから「Set On Enter Only」 を選択する Enterキーを押したときにだけアクションが送られるように なる
  52. 52. ユーザインタフェースのデザインテキストフィールドの設定編集可能なテキストフィールドを選択する インスペクタパネルのAttributesタブの「Action」と 書かれているポップアップメニューから「Set On Enter Only」 を選択する Enterキーを押したときにだけアクションが送られるように なる
  53. 53. ユーザインタフェースのデザインテキストフィールドの設定編集可能なテキストフィールドを選択する インスペクタパネルのAttributesタブの「Action」と 書かれているポップアップメニューから「Set On Enter Only」 を選択する Enterキーを押したときにだけアクションが送られるように なる
  54. 54. ユーザインタフェースのデザインテーブルビューの設定テーブルビューをクリックするインスペクタのタイトルバーに「Scroll View」と表示されていれば,テーブルビューの外側に位置するスクロールビューを選択していることになる
  55. 55. ユーザインタフェースのデザインテーブルビューの設定スクロールビューが選択されている状態で設定を行う横スクロールバーを表示しないようにする インスペクタのAttributesタブにある 「Show Horizontal Scroller」の チェックを外す
  56. 56. ユーザインタフェースのデザインテーブルビューの設定Scroll Viewの状態でテーブルをもう一度クリックする インスペクタのタイトルが「Table View」になる スクロールビュー内部のテーブルビューが選択できている事 を示している
  57. 57. ユーザインタフェースのデザインテーブルビューの設定「Col. Sizing」というポップアップメニューから「Uniform」を選択する これでテーブルビューの 大きさを変更したとき, 列サイズも均等に 変わる事になる
  58. 58. ユーザインタフェースのデザインテーブルビューの設定テーブルのヘッダ部分をクリックする タイトルが「Table Header View」となる さらにクリックして,ヘッダのみが白く強調され 他がグレーアウトになるようにする この状態で列の境目をドラッグして,列の大きさが調整できる
  59. 59. ユーザインタフェースのデザインテーブルビューの設定ヘッダをダブルクリックする事で 列にタイトルを設定できる 左側に「Title」右側に「Link」を入力する
  60. 60. ユーザインタフェースのデザインテーブルビューの設定列の識別子を設定する 「Table Column」と呼ばれる項目を選択する必要がある 再び「Table View」を選択した状態にする この状態でテーブルビューの左側の領域をクリック 左側だけが強調されて,インスペクタのタイトルが 「Table Column」となる
  61. 61. ユーザインタフェースのデザインテーブルビューの設定識別子の設定をする インスペクタに「Identifier」 という項目がある Title列は「title」,Link列 には「link」と入力する 「Editable」のチェックを それぞれ外す
  62. 62. 自動リサイズの設定自動リサイズの設定をするURLテキストフィールドの設定をおこなう 「URL:」と書いてあるテキストフィールドを選択して インスペクタのSizeタブも表示する このテキストフィールドは左上に固定する Autosizingの設定で外側の左と上の設定をする
  63. 63. 自動リサイズの設定同様にすべての部品を設定する「Title:」,「Link:」のテキストフィールドは左上固定編集可能なテキストフィールド,「title」,「link」のテキストフィールドは上に固定で横方向にはリサイズ「Read」ボタンは右上固定テーブルビューはスクロールビューの中に入れられている リサイズの設定は外側のスクロールビューに対しておこなう
  64. 64. 自動リサイズの設定
  65. 65. ウィンドウの設定ウィンドウのタイトルを設定するウィンドウを選択して,インスペクタのAttributesのタブを表示する「Title」というテキストフィールドに,「RSS Reader」と入力する
  66. 66. クラスのインスタンス化クラスをインスタンス化するライブラリの[Cocoa] > [Objects&Controller] > [Controllers]にあるObjectをxibウィンドウにドラッグして追加オブジェクトを選択したままインスペクタを表示し,Identityタブで「AppController」クラスを選択する
  67. 67. アウトレットとアクションの 接続テキストフィールドの titleTextFieldアウトレットを接続す urlTextField linkTextFieldる「urlTextField」,「titleTextField」,「linkTextField」をコントロールキーを押しながらそれぞれ接続する
  68. 68. アウトレットとアクションの 接続アクションの接続をする「Read」ボタンから,「readURL;」アクションに接続する入力可能なテキストフィールドからも「readURL ;」アクションに接続する readURL; readURL; このアクションはテキスト フィールドで Enterキーを 押したときに送られる
  69. 69. アウトレットとアクションの 接続テーブルビューのアウトレットを接続するコントロールをしながらテーブルビューをクリックし,AppControllerまでドラッグして,上でドロップする dataSourceテーブルビューアウトレットの中から「dataSource」を選択
  70. 70. AppControllerクラスの実装AppController.mを編集する ソースコードの内容は次のスライドから…
  71. 71. #import "AppController.h"@implementation AppController- (IBAction)readURL:(id)sender{ NSURL* url; url = [NSURL URLWithString:[urlTextField stringValue]]; // XMLドキュメントを作成します document = [[NSXMLDocument alloc] initWithContentsOfURL:url options:0error: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]; }
  72. 72. 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]; }
  73. 73. 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; }
  74. 74. // /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];}
  75. 75. // 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]; }
  76. 76. // 指定された行の、ノードを取得します 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
  77. 77. ビルドと実行ビルドして実行する[ビルド]→[ビルドと実行]メニューを選択する RSS Readerのアプリケーションが 起動する
  78. 78. おわり

×