SlideShare ist ein Scribd-Unternehmen logo
1 von 32
Downloaden Sie, um offline zu lesen
第3回 iPhone勉強会




13年3月17日日曜日
今後の予定

      ・第3回 他の画面の値を変更する方法
           MVCモデル、タイマーの使い方
      ・第4回 TableView
           ユーザ操作(タップなど)の検出方法
      ・第5回 MapKitを使った地図の表示方法
           現在地の取得方法



13年3月17日日曜日
今日のアジェンダ

         ・前回の復習
         ・他の画面の値を設定する
         ・MVCモデル
         ・タイマー(一定時間ごとに処理を実行)
         ・サンプルアプリ作成



13年3月17日日曜日

今日のスケジュールは以下の通りです。
まず、前回の復習を軽く行った後、他のオブジェクトの値変更の仕方およびMVCモデルについて説明した後、
時間がありそうだったら、タイマーとテーブルビューの説明をいたします。
その後、今日の課題となるサンプルアプリを作成いたします。
今日も出来るだけ手を動かすようにしたいと思います。よろしくおねがいいたします。
前回の復習
       ∼以下のようなアプリを作ってみましょう∼




         押すと次の画面へ移動する         動かすとフォントサイズが変
                                   わる



13年3月17日日曜日

まず、前回の復習をしましょう。
前回受講したという前提で、まずはコードを書いてみます。
図のようなアプリを作ってみましょう。
iPhone上でボタンを押したら次の画面が表示される
何のことだかさっぱりわからないと言う方、こっそり教えてください・・・。
制限時間は20分とします。
他の画面の値を設定する

                                       view2
                  view1
                                      fontSize


                   view1でview2のフォントサイズを変えたい


              view2というオブジェクトにアクセスして
                    フォントサイズを変える


13年3月17日日曜日

ある画面で設定した値を他の画面へ反映するようにしたいと思うのではないでしょうか。
図のようにview1でview2のフォントサイズを変更するという処理をするにはどうすればいいでしょうか。
ここでよく思い出してみましょう。
Objective-CはJavaと同じオブジェクト指向です。
Javaのときはどうしていたでしょうか。。。
Hoge hoge = new Hoge();
hoge.setMoge(“AAA”);
などとというようにオブジェクトにアクセスして値を変更していたと思います。
他のオブジェクトにアクセスする方法

     //View2というオブジェクトを作る
     (またはどこかからもってくる)                             view2
     View2 *view2 = [[View2 alloc]init];        fontSize

     //View2というオブジェクトの
                                           「fontSizeを変更する」とい
     fontSizeを変更する                            うメッセージを送る
     view2.fontSize = 12;




13年3月17日日曜日

Objective-Cでもおなじことです。
View2というオブジェクトを新しく作成するかまたはどこかから取得して、
View2というオブジェクトに対して「フォントサイズを変更してくれ」というメッセージを送るのです。
「復習」での具体例

      ・

              ViewController                DetailViewController



                       DetailViewControllerの値を変更したい



                  どちらかをやりたい
   ViewControllerからDetailViewControllerの値を変更
   DetailViewControllerからViewControllerの値を取得
13年3月17日日曜日

では、復習で行った場合の具体例を見ていきましょう。
実装の都合上、ViewControllerで設定した値をDetailViewControllerで表示するというようにします。
この場合ですと、ViewControllerクラスからDetailViewControllerに対してアクセスするか、DetailViewControllerクラスあ
らViewControllerクラスにアクセスすればいいのです。
どうすればいいのでしょうか
既にViewController、DetailViewControllerで画面を作っているため、オブジェクト自体を新しく作り直す訳にはいきませ
ん。
いくつかやり方はあるのですが1つ紹介します。
ViewControllerから
         DetailViewControllerの値を変更する

          ViewController
                                                DetailViewController
- (void)prepareForSegue:
(UIStoryBoardSegue*)se                       float(nonatmic) fontSize;
           gue                               UILabel *label




  ViewControllerからDetailViewControllerに遷移すると
  きに値を変更
13年3月17日日曜日

先ほど復習で使ったプロジェクトを編集し、ViewControllerで設定したフォントサイズで
DetailViewControllerの画面を表示するようにしましょう。
まず、StoryBoard画面を開いて、ViewControllerにSliderとStepperを配置し、ヘッダファイルに反映させましょう。
そして、ViewController.mに
- (void)prepareForSegue:(UIStoryBoardSegue*)segueというメソッドを記載してください。
2つのViewControllerにアクセスする
                  メソッド
- (void)prepareForSegue:(UIStoryBoardSegue*)segue
ボタンを押したとき(viewを移動するとき)に呼ばれるメソッド


UIStoryBoardSegue:
2つのViewControllerを行き来するときに使うオブジェクト
sourceViewController:(遷移元のViewController)
destinationViewController:(遷移先のViewController)




13年3月17日日曜日

- (void)prepareForSegue:(UIStoryBoardSegue*)segueは
ボタンを押してViewを移動するときに呼ばれるメソッドで、引数のsegueには
sourceViewControllerという遷移先のViewControllerとdestinationViewControllerという
遷移先のViewControllerが格納されています。
ここではdestinationViewControllerへアクセスすることで遷移先のViewControllerで保持している値を変更することが出来
ます。
2つのViewControllerにアクセスする
                  メソッド

- (void)prepareForSegue:(UIStoryBoardSegue*)segue
ヘッダファイルに宣言していないのになぜエラーにならない?



                     prepareForSegue は
              UIViewControllerで宣言されているから




13年3月17日日曜日

ViewController.mのみに - (void)prepareForSegue:(UIStoryBoardSegue*)segueを記載したと思いますが、
ヘッダファイルに宣言しない状態でビルドしてもエラーになりません。
なぜかというと、親クラスであるUIViewControllerで宣言されているからです。
ViewControllerから
          DetailViewControllerの値を変更する

- (void)prepareForSegue:(UIStoryBoardSegue*)segue
 の中身

DetailViewController *detailViewController = (DetailViewController
*)segue.destinationViewController;
    detailViewController.label.font =
   [UIFont fontWithName:@"Helvetica" size:self.fontSize];

                                                    DetailViewController型にキャス
                                                              トしている



13年3月17日日曜日

- (void)prepareForSegue:(UIStoryBoardSegue*)segue
の中身を実装しましょう。
segueのdestinatinationViewControllerに遷移先のViewController(ここではDetailViewController)
が格納されているので、取得してみましょう。取得したDetailViewControllerのlabelの値を変更してみましょう。
こ 状 で ン イ し 実 し す                                                    
 の 態 コ パ ル て 行 ま 。                                                    
ViewControllerから
         DetailViewControllerの値を変更する


      動かしてみて、フォントサイズは変わりましたか?

      実は、これだとフォントサイズは変わらないのです。
      なぜでしょう・・・。


      なぜか知るために、デバッグしてみましょう。




13年3月17日日曜日

コンパイルして実行してみましょう。
フォントサイズは変わりましたか?変わっていませんね。なぜでしょうか。
なぜか知るためにデバッグしてみましょう。Xcodeでブレークポイントを貼ってみましょう。
デバッガを使ってみよう
    Xcodeを立ち上げて、以下のようにブレークポイントを
    設定します。


                                            detailViewController.labelが
                                                   nilになっている




13年3月17日日曜日

コンパイルして実行してみましょう。
フォントサイズは変わりましたか?変わっていませんね。なぜでしょうか。
なぜか知るためにデバッグしてみましょう。画面のようにXcodeでブレークポイントを設定して実行してみましょう。
detailViewController.labelがnilになっているのがわかりますか?
nilに対して設定しても値は変わらないのです。なので、値が変わらなかったのです。
ここで湧く2つの疑問


        ■疑問その1:
        nilにアクセスして大丈夫なの?
        (そもそもnilって何)


        ■疑問その2:
        何でdetailViewController.labelがnilなの?




13年3月17日日曜日

ここで2つの疑問が湧くと思います。
まず、nilにアクセスしても大丈夫なのか(そもそも、nilって何?)ということと何でdetailViewController.labelがnilなのか
ということです。
nilとは?


              空のポインタ、無効なオブジェクト
              ちなみに、値は0

                                          nilはid型の空ポインタで値は0




              メッセージを送るとどうなる?
              →何も送られない。




13年3月17日日曜日

ここで改めて、「nil」とは何かということを説明します。
nilとは無効なオブジェクトのことで、空のポインタです。ちなみに値は0です。
デバッガで表示されている値を見てみましょう。0x00000000となっていると思います。
javaで言えばNULLと同じようなものなのですが、nilに対してメッセージを送っても落ちるということは無く、
何も処理が行われません。
なので、detailViewController.labelにアクセスしようとしても、何も行われなかったのです。
参照(strongとweak)

       DetailViewController.hの中身

       @property (weak, nonatomic) IBOutlet UILabel
       *label;

                               弱い参照を表している



     strong(デフォルト):強い参照。
     誰も参照しなくなったらオブジェクトが消滅する
     weak:弱い参照。
     変数スコープを超えるとオブジェクトが消滅する


13年3月17日日曜日

では、なぜDetailViewControllerの中身がnilだったのでしょうか。
DetailViewController.hの中身を見てみましょう。
@property (weak, nonatomic) IBOutlet UILabel *labelと書かれているのではないでしょうか。
ここで注目していただきたいのは、@propertyの後のweakという文字です。
これはオブジェクトが強い参照か弱い参照かを表しています。デフォルトではstrongが設定されています。
Objective-Cはリファレンスカウンタ方式をとっており、そのオブジェクトが誰からも参照されなくなったらメモリ上から消
えるようになっています。「強い参照」ではオブジェクトが誰からも参照されなくなったらメモリから解放されます。(消滅
します)「弱い参照」ではオブジェクトは変数スコープを超えるとメモリから解放されます。
なぜ弱い参照が必要?

       オブジェクト同士が参照し合っている状態を考えて
       みましょう。

                            Object2への強い参照

              Object1                        Object2
                            Object1への強い参照



      これだといつまでたってもオブジェクトが解放されず、
      メモリリークになる


13年3月17日日曜日

なぜ、弱い参照が必要なのでしょうか。
強い参照だけだと困る場合があるのです。図のようにオブジェクト同士が参照し合っている状態を考えてみます。
Object1はObject2を参照し、Object2はObject1を参照します。
いわゆる、循環参照という状態です。
この場合、参照状態が消滅することが無いので、いつまでたってもオブジェクトが残り続けることになります。
オブジェクトが残り続けるとメモリリークとなりアプリが落ちてしまう原因にもなるのでさけなくてはならないのです。
なぜ弱い参照が必要?

       Object2にweakをつけて弱い参照にすると・・・


                        Object2への弱い参照

              Object1                            Object2
                        Object1への強い参照



      Object2はスコープを超えると消滅し、Object1に対し
      ての参照も消滅する


13年3月17日日曜日

ここでObject2に対してweakをつけて弱い参照にするとどうなるでしょうか。
Object1はObject2に対して弱い参照を持っていることになります。
Object2はスコープをこえると消滅してしまい、同時にObject1への参照も消滅します。
つまり、オブジェクトがいつまでも残り続けるということがなくなると言うわけです。
例題の場合

       InterfaceBuilderでlabelを貼付けることにより
       DetailViewControllerのviewがlabelを参照


                                labelへの参照

                view                                     label




13年3月17日日曜日

例題の場合、InterfaceBuilderでlabelをviewに貼付けることで、detailViewControllerのviewがlabelを参照することになり
ます。
しかし、viewが消滅したときには貼付けているlabelを見ることはありません。
なので、弱い参照としてviewが消滅すると同時にlabelも消滅させてしまうのです。
では、どうすればいい?
       DetailViewController.hに以下を追加します。
       @property (nonatomic)float fontSize;


       そして、DetailViewController.mに以下を追加します
                                    Viewを表示するときに呼ばれ
       ・viewWillAppear                    るメソッド

       self.label.font = [UIFont fontWithName:@"Helvetica"
       size:self.fontSize];


       さらに、ViewController.mに以下を追加します
       ・prepareForSegue
       detailViewController.fontSize = self.slider.value;


13年3月17日日曜日

ではどうすればいいでしょうか。
labelを直接変更せず、フォントサイズを渡してあげればよいのです。
DetailViewControllerでは受け取ったフォントサイズを反映します。
DetailViewControllerの親クラスであるUIViewControllerでは、viewを表示する直前にviewWilAppearというメソッドが呼
ばれます。そこでlabelに渡されたフォントサイズを反映させてあげればいいのです。
さらにViewController.mのprepareForSegueではDetailViewControllerで定義したfontSizeの値を変更しましょう。
ちなみに、fontSizeはオブジェクトではなくプリミティブな値なので、メモリは自動解放されます。
なので、strongやweakをきにする必要はありません。
ここまでのまとめ


              ・他のオブジェクトの値の変更
              ・デバッグ
              ・nilについて
              ・強い参照と弱い参照




13年3月17日日曜日

無事に動いたでしょうか。
ここまでのおさらいをします。
まず、他のオブジェクトに対して値を変更する方法を勉強しました。
デバッガの起動方法も触れましたね。nilが何かということも勉強しました。
強い参照と弱い参照にも触れました。
ここでやったことはかなり難しいです。今すぐにすべてを理解するのは大変なので、開発がある程度で切るようになったらも
う一度見直していただけるとうれしいです。
MVCモデル

       ここで、他の値も設定するようにプログラムを
       変えてみましょう。


     数カ所だけならまだしも、何個も変更する値が
     あるとめんどくさい
     →そこでMVCモデルを使う



13年3月17日日曜日

今までの話で、画面で設定したものを他の画面へ反映する方法を学んだので、他のパーツを追加し、
変更した値を反映するようにしましょう。
いちいちすべての値を渡すのは大変です。一つのオブジェクトとしてまとめた方が楽です。
そのような要求に応えてくれるのがMVCモデルです。これからMVCモデルについて勉強していきます。

Javaなどでも画面で設定したものをデータオブジェクトに保持するなんてことを行っているかと思います。
Objective-Cでも同じです。iPhoneアプリの開発ではMVCモデルに基づいて開発します。
釈   に説法かも知れないですが、MVCモデルについておさらいします。
Modelでデータの保持およびデータの操作を行います。
ViewでModelのデータを画面に表示します。
Controllerでユーザの操作の受付およびモデルの操作を行います。Viewに対するControllerということでViewControllerを使
っていた訳です。
MVCモデル

                                 Model

                      データおよびデータの操作


              View                                   Controller


         Modelのデータを                             ユーザ操作の受付
         画面へ表示                                  モデルの操作

13年3月17日日曜日


Objective-Cでも同じです。iPhoneアプリの開発ではMVCモデルに基づいて開発します。
釈   に説法かも知れないですが、MVCモデルについておさらいします。
Modelでデータの保持およびデータの操作を行います。
ViewでModelのデータを画面に表示します。
Controllerでユーザの操作の受付およびモデルの操作を行います。Viewに対するControllerということでViewControllerを使
っていた訳です。
Modelを作成してみよう

        ・会員(Member)というモデルを作成


        ∼モデルのデータ∼
        ・会員番号 
         変数名:memberId 型:int型
        ・会員名
         変数名:memberName 型:NSString型



        このモデルを実現するオブジェクトを作成するには?

13年3月17日日曜日

ViewとControllerについては既に作成しているので、今度はViewで入力したデータを保持するモデルを作成しましょう。
例えば会員(Member)というモデルを作成する例を考えてみます。
モデルの中身は、int型の会員番号とNSString型の会員名とします。この場合、どのようにオブジェクトを作成するにはどう
したらいいでしょうか。
Modelを作成してみよう


         必要なもの
         ・.hファイル(Model.h)
         ・.mファイル (Model.m)


         ・.hファイルの中身
         @property(nonatomic,strong) NSString *memberName;
         @property(nonatomic)int memberId;




13年3月17日日曜日

必要なものは.hファイルと.mファイルです。
メニューのFile→New→Fileを選んで新しいファイルを作成します。
Objective-C Classを選択して次に進んでください。
ClassにはMember、SubClassにはNSObjectを記載して保存してください。
そうすると、Model.hとModel.mが作成されます。Model.hにmemberNameとmemberIdを宣言してください。
@propertyをつけるとgetterとsetterが作成されるので、特にModel.mの記載はいりません。
シングルトン
       どこからでもアクセスできるシングルトンにします。
       ・Model.hに以下の記載を追加
       +(Member *)sharedInstance;

       ・Model.mに以下の記載を追加
       static Member *member = nil;

       @implementation Member

       +(Member *)sharedInstance{
           if (member == nil) {
               member = [[super alloc]init];
           }
           return member;
       }


13年3月17日日曜日

このままでもいいのですが、どこからでもアクセスできるようにシングルトンにします。
(データを外部ファイルに保存していないので)
Model.hには以下のように記載してください。
+(Member *)sharedInstance;+というのは、クラスメソッドであるということです。
つまり、オブジェクトではなく、クラスに対してメッセージを送るということです。
ここではMemberというクラスに対してsharedInstanceというメッセージを送るとMemberがたのオブジェクトが返ってき
ます。
Model.mファイルにはsharedInstanceメソッドの実装を行います。
まず、staticをつけることにより、ファイル内だけで有効となります。(ほかのオブジェクトからアクセスできないようにな
ります)
そして sharedInstanceが呼ばれたときは、nilであるかどうかチェックをして、nilだった場合のみ初期化します。
値の参照方法

      値を参照するには以下のように記述します

      [Member sharedInstance]. memberName;


                                これでMember型のオブジェ
                                    クトを取得




      取得した値を表示させてみましょう




13年3月17日日曜日

Member型のオブジェクトに設定した値を参照するには
[Member sharedInstance]を使ってオブジェクトを取得します。
取得したオブジェクトの値を参照してください。
MVCTestというプロジェクトをに詳細のコードを記載しておりますので、見てみましょう。
一定時間ごとに処理を行う

        NSTimerを使うと一定間隔で同じメソッドを呼び
        出すことが出来る



    [NSTimer scheduledTimerWithTimeInterval:0.5
                                     target:self
                                   selector:@selector(increment:)
                                   userInfo:nil
       タイマーを初期化して開始す
                                    repeats:YES];
              るメソッド
     [timer invalidate];          タイマーを止めるメソッド


       [timer fire];             タイマーを開始するメソッド



13年3月17日日曜日

ここで前回リクエストがあったので、「一定時間ごとに値が更新されるプログラム」について説明をします。NSTimerという
クラスを使うと、一定時間間隔で同じメソッドを呼び出すことが出来ます。
お渡ししたファイルにNSTimerTestというプロジェクトがありますので、そちらをご覧ください。
一定時間ごとに処理を行う


        @selectorって何??
        →コンパイラに「この引数はメソッドである(SEL
        型)」ことを示すもの

     [NSTimer scheduledTimerWithTimeInterval:0.5
                                      target:self
                                    selector:@selector(increment:)
                                    userInfo:nil
                                     repeats:YES];

                                           incrementというメソッドを
                                                  渡している



13年3月17日日曜日

ここで@selectorについて少し解説します。
@selectorとはコンパイラに対して「この引数はメソッド(関数)である」ということを教えています。
SEL型と言います。ここで使用しているNSTimerでは自分自身のメソッドを繰り返し呼び出しています。
今日のまとめ


              ・他のオブジェクトの値の変更
              ・MVCモデル
              ・タイマーの使い方




13年3月17日日曜日

では、今日の課題に入る前におさらいをしましょう
最初に他のオブジェクトの値の変更する方法を勉強しました。
そして、MVCモデルを使って色々な画面から値を参照できるようにしました。
おまけにタイマーの使い方を勉強しました。
今日の課題




13年3月17日日曜日

では、今日の課題です。
このようにボタンを押したら項目の編集を行い、編集結果を反映できるようにしてみてください
ご清聴ありがとうございました




13年3月17日日曜日

Weitere ähnliche Inhalte

Andere mochten auch

Andere mochten auch (20)

Indices 06 mar 2014
Indices 06 mar 2014Indices 06 mar 2014
Indices 06 mar 2014
 
Búsqueda Bibliográfica en PubMed 2
Búsqueda Bibliográfica en PubMed 2Búsqueda Bibliográfica en PubMed 2
Búsqueda Bibliográfica en PubMed 2
 
Finalaya daily market wrap 07 April 2014
Finalaya daily market wrap 07 April 2014Finalaya daily market wrap 07 April 2014
Finalaya daily market wrap 07 April 2014
 
Indices 20 feb 2014
Indices 20 feb 2014Indices 20 feb 2014
Indices 20 feb 2014
 
Campanie de constientizare ACBCC
Campanie de constientizare ACBCCCampanie de constientizare ACBCC
Campanie de constientizare ACBCC
 
Indices 02 may 2014
Indices 02 may 2014Indices 02 may 2014
Indices 02 may 2014
 
Nina carlsen catching fire
Nina carlsen catching fireNina carlsen catching fire
Nina carlsen catching fire
 
Aplikasi garis panduan dan etika penggunaan internet
Aplikasi garis panduan dan etika penggunaan internetAplikasi garis panduan dan etika penggunaan internet
Aplikasi garis panduan dan etika penggunaan internet
 
Indices 14 jan2013051711
Indices 14 jan2013051711Indices 14 jan2013051711
Indices 14 jan2013051711
 
Indices 04 jul2013073804
Indices 04 jul2013073804Indices 04 jul2013073804
Indices 04 jul2013073804
 
Indices 05 aug2013055239
Indices 05 aug2013055239Indices 05 aug2013055239
Indices 05 aug2013055239
 
ATG Title
ATG TitleATG Title
ATG Title
 
Entrepreneur's World #8
Entrepreneur's World #8Entrepreneur's World #8
Entrepreneur's World #8
 
Indices 04 mar2013063301
Indices 04 mar2013063301Indices 04 mar2013063301
Indices 04 mar2013063301
 
4444444454545
44444444545454444444454545
4444444454545
 
My fivefirefox
My fivefirefoxMy fivefirefox
My fivefirefox
 
Indices 30 nov2012071309
Indices 30 nov2012071309Indices 30 nov2012071309
Indices 30 nov2012071309
 
Indices 06 Jan 2014
Indices 06 Jan 2014Indices 06 Jan 2014
Indices 06 Jan 2014
 
Indices 20 aug2013082020
Indices 20 aug2013082020Indices 20 aug2013082020
Indices 20 aug2013082020
 
Indices 16 aug2013062420
Indices 16 aug2013062420Indices 16 aug2013062420
Indices 16 aug2013062420
 

Ähnlich wie I phoneアプリ入門 第3回

I phoneアプリ入門 第4回
I phoneアプリ入門 第4回I phoneアプリ入門 第4回
I phoneアプリ入門 第4回Sachiko Kajishima
 
Introduction for Browser Side MVC
Introduction for Browser Side MVCIntroduction for Browser Side MVC
Introduction for Browser Side MVCRyunosuke SATO
 
GUI アプリケーションにおける MVC
GUI アプリケーションにおける MVCGUI アプリケーションにおける MVC
GUI アプリケーションにおける MVCYu Nobuoka
 
RxDataSourceをNSDiffableDataSourceへ置き換える際のTips集紹介
RxDataSourceをNSDiffableDataSourceへ置き換える際のTips集紹介RxDataSourceをNSDiffableDataSourceへ置き換える際のTips集紹介
RxDataSourceをNSDiffableDataSourceへ置き換える際のTips集紹介Fumiya Sakai
 
ASP.NET MVC 2 ~新機能の紹介~
ASP.NET MVC 2 ~新機能の紹介~ASP.NET MVC 2 ~新機能の紹介~
ASP.NET MVC 2 ~新機能の紹介~Yoshitaka Seo
 
Flutterでscroll viewとexpandedを併用してsign in sign up画面 などの レイアウトを作成する
Flutterでscroll viewとexpandedを併用してsign in sign up画面 などの レイアウトを作成するFlutterでscroll viewとexpandedを併用してsign in sign up画面 などの レイアウトを作成する
Flutterでscroll viewとexpandedを併用してsign in sign up画面 などの レイアウトを作成するIgaHironobu
 
Xamarin.formsでのmvvm利用のコツ
Xamarin.formsでのmvvm利用のコツXamarin.formsでのmvvm利用のコツ
Xamarin.formsでのmvvm利用のコツMasuda Tomoaki
 
mobylet ケータイサイト30分クッキング
mobylet ケータイサイト30分クッキングmobylet ケータイサイト30分クッキング
mobylet ケータイサイト30分クッキングShin Takeuchi
 
20130125 titanium meetupvol5
20130125 titanium meetupvol520130125 titanium meetupvol5
20130125 titanium meetupvol5Hiroshi Oyamada
 
スマートフォン勉強会関西#16(iOS,Android,WP7マルチタッチ)
スマートフォン勉強会関西#16(iOS,Android,WP7マルチタッチ)スマートフォン勉強会関西#16(iOS,Android,WP7マルチタッチ)
スマートフォン勉強会関西#16(iOS,Android,WP7マルチタッチ)Tomonori Ohba
 
RIAアーキテクチャー研究会 第3回 セッション4 Mvpvm pattern
RIAアーキテクチャー研究会 第3回 セッション4 Mvpvm patternRIAアーキテクチャー研究会 第3回 セッション4 Mvpvm pattern
RIAアーキテクチャー研究会 第3回 セッション4 Mvpvm patternMami Shiino
 
Windows phone & windows 8で見えてくるメトロの世界
Windows phone & windows 8で見えてくるメトロの世界Windows phone & windows 8で見えてくるメトロの世界
Windows phone & windows 8で見えてくるメトロの世界Makoto Nishimura
 
UICollectionViewLayoutでカバーフローを作りたい!
UICollectionViewLayoutでカバーフローを作りたい!UICollectionViewLayoutでカバーフローを作りたい!
UICollectionViewLayoutでカバーフローを作りたい!sawat1203
 
Mithril - 軽量/高速なMVCフレームワーク
Mithril - 軽量/高速なMVCフレームワークMithril - 軽量/高速なMVCフレームワーク
Mithril - 軽量/高速なMVCフレームワークsairoutine
 

Ähnlich wie I phoneアプリ入門 第3回 (20)

I phoneアプリ入門 第4回
I phoneアプリ入門 第4回I phoneアプリ入門 第4回
I phoneアプリ入門 第4回
 
Introduction for Browser Side MVC
Introduction for Browser Side MVCIntroduction for Browser Side MVC
Introduction for Browser Side MVC
 
GUI アプリケーションにおける MVC
GUI アプリケーションにおける MVCGUI アプリケーションにおける MVC
GUI アプリケーションにおける MVC
 
RxDataSourceをNSDiffableDataSourceへ置き換える際のTips集紹介
RxDataSourceをNSDiffableDataSourceへ置き換える際のTips集紹介RxDataSourceをNSDiffableDataSourceへ置き換える際のTips集紹介
RxDataSourceをNSDiffableDataSourceへ置き換える際のTips集紹介
 
ASP.NET MVC 2 ~新機能の紹介~
ASP.NET MVC 2 ~新機能の紹介~ASP.NET MVC 2 ~新機能の紹介~
ASP.NET MVC 2 ~新機能の紹介~
 
Flutterでscroll viewとexpandedを併用してsign in sign up画面 などの レイアウトを作成する
Flutterでscroll viewとexpandedを併用してsign in sign up画面 などの レイアウトを作成するFlutterでscroll viewとexpandedを併用してsign in sign up画面 などの レイアウトを作成する
Flutterでscroll viewとexpandedを併用してsign in sign up画面 などの レイアウトを作成する
 
Xamarin.formsでのmvvm利用のコツ
Xamarin.formsでのmvvm利用のコツXamarin.formsでのmvvm利用のコツ
Xamarin.formsでのmvvm利用のコツ
 
mobylet ケータイサイト30分クッキング
mobylet ケータイサイト30分クッキングmobylet ケータイサイト30分クッキング
mobylet ケータイサイト30分クッキング
 
20130125 titanium meetupvol5
20130125 titanium meetupvol520130125 titanium meetupvol5
20130125 titanium meetupvol5
 
Knockout
KnockoutKnockout
Knockout
 
スマートフォン勉強会関西#16(iOS,Android,WP7マルチタッチ)
スマートフォン勉強会関西#16(iOS,Android,WP7マルチタッチ)スマートフォン勉強会関西#16(iOS,Android,WP7マルチタッチ)
スマートフォン勉強会関西#16(iOS,Android,WP7マルチタッチ)
 
MVVM入門
MVVM入門MVVM入門
MVVM入門
 
Swift study vol.03
Swift study vol.03Swift study vol.03
Swift study vol.03
 
Mvpvm pattern
Mvpvm patternMvpvm pattern
Mvpvm pattern
 
Storyboard
StoryboardStoryboard
Storyboard
 
ScalaMatsuri 2016
ScalaMatsuri 2016ScalaMatsuri 2016
ScalaMatsuri 2016
 
RIAアーキテクチャー研究会 第3回 セッション4 Mvpvm pattern
RIAアーキテクチャー研究会 第3回 セッション4 Mvpvm patternRIAアーキテクチャー研究会 第3回 セッション4 Mvpvm pattern
RIAアーキテクチャー研究会 第3回 セッション4 Mvpvm pattern
 
Windows phone & windows 8で見えてくるメトロの世界
Windows phone & windows 8で見えてくるメトロの世界Windows phone & windows 8で見えてくるメトロの世界
Windows phone & windows 8で見えてくるメトロの世界
 
UICollectionViewLayoutでカバーフローを作りたい!
UICollectionViewLayoutでカバーフローを作りたい!UICollectionViewLayoutでカバーフローを作りたい!
UICollectionViewLayoutでカバーフローを作りたい!
 
Mithril - 軽量/高速なMVCフレームワーク
Mithril - 軽量/高速なMVCフレームワークMithril - 軽量/高速なMVCフレームワーク
Mithril - 軽量/高速なMVCフレームワーク
 

I phoneアプリ入門 第3回

  • 2. 今後の予定 ・第3回 他の画面の値を変更する方法 MVCモデル、タイマーの使い方 ・第4回 TableView ユーザ操作(タップなど)の検出方法 ・第5回 MapKitを使った地図の表示方法 現在地の取得方法 13年3月17日日曜日
  • 3. 今日のアジェンダ ・前回の復習 ・他の画面の値を設定する ・MVCモデル ・タイマー(一定時間ごとに処理を実行) ・サンプルアプリ作成 13年3月17日日曜日 今日のスケジュールは以下の通りです。 まず、前回の復習を軽く行った後、他のオブジェクトの値変更の仕方およびMVCモデルについて説明した後、 時間がありそうだったら、タイマーとテーブルビューの説明をいたします。 その後、今日の課題となるサンプルアプリを作成いたします。 今日も出来るだけ手を動かすようにしたいと思います。よろしくおねがいいたします。
  • 4. 前回の復習 ∼以下のようなアプリを作ってみましょう∼ 押すと次の画面へ移動する 動かすとフォントサイズが変 わる 13年3月17日日曜日 まず、前回の復習をしましょう。 前回受講したという前提で、まずはコードを書いてみます。 図のようなアプリを作ってみましょう。 iPhone上でボタンを押したら次の画面が表示される 何のことだかさっぱりわからないと言う方、こっそり教えてください・・・。 制限時間は20分とします。
  • 5. 他の画面の値を設定する view2 view1 fontSize view1でview2のフォントサイズを変えたい view2というオブジェクトにアクセスして フォントサイズを変える 13年3月17日日曜日 ある画面で設定した値を他の画面へ反映するようにしたいと思うのではないでしょうか。 図のようにview1でview2のフォントサイズを変更するという処理をするにはどうすればいいでしょうか。 ここでよく思い出してみましょう。 Objective-CはJavaと同じオブジェクト指向です。 Javaのときはどうしていたでしょうか。。。 Hoge hoge = new Hoge(); hoge.setMoge(“AAA”); などとというようにオブジェクトにアクセスして値を変更していたと思います。
  • 6. 他のオブジェクトにアクセスする方法 //View2というオブジェクトを作る (またはどこかからもってくる) view2 View2 *view2 = [[View2 alloc]init]; fontSize //View2というオブジェクトの 「fontSizeを変更する」とい fontSizeを変更する うメッセージを送る view2.fontSize = 12; 13年3月17日日曜日 Objective-Cでもおなじことです。 View2というオブジェクトを新しく作成するかまたはどこかから取得して、 View2というオブジェクトに対して「フォントサイズを変更してくれ」というメッセージを送るのです。
  • 7. 「復習」での具体例 ・ ViewController DetailViewController DetailViewControllerの値を変更したい どちらかをやりたい ViewControllerからDetailViewControllerの値を変更 DetailViewControllerからViewControllerの値を取得 13年3月17日日曜日 では、復習で行った場合の具体例を見ていきましょう。 実装の都合上、ViewControllerで設定した値をDetailViewControllerで表示するというようにします。 この場合ですと、ViewControllerクラスからDetailViewControllerに対してアクセスするか、DetailViewControllerクラスあ らViewControllerクラスにアクセスすればいいのです。 どうすればいいのでしょうか 既にViewController、DetailViewControllerで画面を作っているため、オブジェクト自体を新しく作り直す訳にはいきませ ん。 いくつかやり方はあるのですが1つ紹介します。
  • 8. ViewControllerから DetailViewControllerの値を変更する ViewController DetailViewController - (void)prepareForSegue: (UIStoryBoardSegue*)se float(nonatmic) fontSize; gue UILabel *label ViewControllerからDetailViewControllerに遷移すると きに値を変更 13年3月17日日曜日 先ほど復習で使ったプロジェクトを編集し、ViewControllerで設定したフォントサイズで DetailViewControllerの画面を表示するようにしましょう。 まず、StoryBoard画面を開いて、ViewControllerにSliderとStepperを配置し、ヘッダファイルに反映させましょう。 そして、ViewController.mに - (void)prepareForSegue:(UIStoryBoardSegue*)segueというメソッドを記載してください。
  • 9. 2つのViewControllerにアクセスする メソッド - (void)prepareForSegue:(UIStoryBoardSegue*)segue ボタンを押したとき(viewを移動するとき)に呼ばれるメソッド UIStoryBoardSegue: 2つのViewControllerを行き来するときに使うオブジェクト sourceViewController:(遷移元のViewController) destinationViewController:(遷移先のViewController) 13年3月17日日曜日 - (void)prepareForSegue:(UIStoryBoardSegue*)segueは ボタンを押してViewを移動するときに呼ばれるメソッドで、引数のsegueには sourceViewControllerという遷移先のViewControllerとdestinationViewControllerという 遷移先のViewControllerが格納されています。 ここではdestinationViewControllerへアクセスすることで遷移先のViewControllerで保持している値を変更することが出来 ます。
  • 10. 2つのViewControllerにアクセスする メソッド - (void)prepareForSegue:(UIStoryBoardSegue*)segue ヘッダファイルに宣言していないのになぜエラーにならない? prepareForSegue は UIViewControllerで宣言されているから 13年3月17日日曜日 ViewController.mのみに - (void)prepareForSegue:(UIStoryBoardSegue*)segueを記載したと思いますが、 ヘッダファイルに宣言しない状態でビルドしてもエラーになりません。 なぜかというと、親クラスであるUIViewControllerで宣言されているからです。
  • 11. ViewControllerから DetailViewControllerの値を変更する - (void)prepareForSegue:(UIStoryBoardSegue*)segue の中身 DetailViewController *detailViewController = (DetailViewController *)segue.destinationViewController; detailViewController.label.font = [UIFont fontWithName:@"Helvetica" size:self.fontSize]; DetailViewController型にキャス トしている 13年3月17日日曜日 - (void)prepareForSegue:(UIStoryBoardSegue*)segue の中身を実装しましょう。 segueのdestinatinationViewControllerに遷移先のViewController(ここではDetailViewController) が格納されているので、取得してみましょう。取得したDetailViewControllerのlabelの値を変更してみましょう。 こ 状 で ン イ し 実 し す                                                     の 態 コ パ ル て 行 ま 。                                                    
  • 12. ViewControllerから DetailViewControllerの値を変更する 動かしてみて、フォントサイズは変わりましたか? 実は、これだとフォントサイズは変わらないのです。 なぜでしょう・・・。 なぜか知るために、デバッグしてみましょう。 13年3月17日日曜日 コンパイルして実行してみましょう。 フォントサイズは変わりましたか?変わっていませんね。なぜでしょうか。 なぜか知るためにデバッグしてみましょう。Xcodeでブレークポイントを貼ってみましょう。
  • 13. デバッガを使ってみよう Xcodeを立ち上げて、以下のようにブレークポイントを 設定します。 detailViewController.labelが nilになっている 13年3月17日日曜日 コンパイルして実行してみましょう。 フォントサイズは変わりましたか?変わっていませんね。なぜでしょうか。 なぜか知るためにデバッグしてみましょう。画面のようにXcodeでブレークポイントを設定して実行してみましょう。 detailViewController.labelがnilになっているのがわかりますか? nilに対して設定しても値は変わらないのです。なので、値が変わらなかったのです。
  • 14. ここで湧く2つの疑問 ■疑問その1: nilにアクセスして大丈夫なの? (そもそもnilって何) ■疑問その2: 何でdetailViewController.labelがnilなの? 13年3月17日日曜日 ここで2つの疑問が湧くと思います。 まず、nilにアクセスしても大丈夫なのか(そもそも、nilって何?)ということと何でdetailViewController.labelがnilなのか ということです。
  • 15. nilとは? 空のポインタ、無効なオブジェクト ちなみに、値は0 nilはid型の空ポインタで値は0 メッセージを送るとどうなる? →何も送られない。 13年3月17日日曜日 ここで改めて、「nil」とは何かということを説明します。 nilとは無効なオブジェクトのことで、空のポインタです。ちなみに値は0です。 デバッガで表示されている値を見てみましょう。0x00000000となっていると思います。 javaで言えばNULLと同じようなものなのですが、nilに対してメッセージを送っても落ちるということは無く、 何も処理が行われません。 なので、detailViewController.labelにアクセスしようとしても、何も行われなかったのです。
  • 16. 参照(strongとweak) DetailViewController.hの中身 @property (weak, nonatomic) IBOutlet UILabel *label; 弱い参照を表している strong(デフォルト):強い参照。 誰も参照しなくなったらオブジェクトが消滅する weak:弱い参照。 変数スコープを超えるとオブジェクトが消滅する 13年3月17日日曜日 では、なぜDetailViewControllerの中身がnilだったのでしょうか。 DetailViewController.hの中身を見てみましょう。 @property (weak, nonatomic) IBOutlet UILabel *labelと書かれているのではないでしょうか。 ここで注目していただきたいのは、@propertyの後のweakという文字です。 これはオブジェクトが強い参照か弱い参照かを表しています。デフォルトではstrongが設定されています。 Objective-Cはリファレンスカウンタ方式をとっており、そのオブジェクトが誰からも参照されなくなったらメモリ上から消 えるようになっています。「強い参照」ではオブジェクトが誰からも参照されなくなったらメモリから解放されます。(消滅 します)「弱い参照」ではオブジェクトは変数スコープを超えるとメモリから解放されます。
  • 17. なぜ弱い参照が必要? オブジェクト同士が参照し合っている状態を考えて みましょう。 Object2への強い参照 Object1 Object2 Object1への強い参照 これだといつまでたってもオブジェクトが解放されず、 メモリリークになる 13年3月17日日曜日 なぜ、弱い参照が必要なのでしょうか。 強い参照だけだと困る場合があるのです。図のようにオブジェクト同士が参照し合っている状態を考えてみます。 Object1はObject2を参照し、Object2はObject1を参照します。 いわゆる、循環参照という状態です。 この場合、参照状態が消滅することが無いので、いつまでたってもオブジェクトが残り続けることになります。 オブジェクトが残り続けるとメモリリークとなりアプリが落ちてしまう原因にもなるのでさけなくてはならないのです。
  • 18. なぜ弱い参照が必要? Object2にweakをつけて弱い参照にすると・・・ Object2への弱い参照 Object1 Object2 Object1への強い参照 Object2はスコープを超えると消滅し、Object1に対し ての参照も消滅する 13年3月17日日曜日 ここでObject2に対してweakをつけて弱い参照にするとどうなるでしょうか。 Object1はObject2に対して弱い参照を持っていることになります。 Object2はスコープをこえると消滅してしまい、同時にObject1への参照も消滅します。 つまり、オブジェクトがいつまでも残り続けるということがなくなると言うわけです。
  • 19. 例題の場合 InterfaceBuilderでlabelを貼付けることにより DetailViewControllerのviewがlabelを参照 labelへの参照 view label 13年3月17日日曜日 例題の場合、InterfaceBuilderでlabelをviewに貼付けることで、detailViewControllerのviewがlabelを参照することになり ます。 しかし、viewが消滅したときには貼付けているlabelを見ることはありません。 なので、弱い参照としてviewが消滅すると同時にlabelも消滅させてしまうのです。
  • 20. では、どうすればいい? DetailViewController.hに以下を追加します。 @property (nonatomic)float fontSize; そして、DetailViewController.mに以下を追加します Viewを表示するときに呼ばれ ・viewWillAppear るメソッド self.label.font = [UIFont fontWithName:@"Helvetica" size:self.fontSize]; さらに、ViewController.mに以下を追加します ・prepareForSegue detailViewController.fontSize = self.slider.value; 13年3月17日日曜日 ではどうすればいいでしょうか。 labelを直接変更せず、フォントサイズを渡してあげればよいのです。 DetailViewControllerでは受け取ったフォントサイズを反映します。 DetailViewControllerの親クラスであるUIViewControllerでは、viewを表示する直前にviewWilAppearというメソッドが呼 ばれます。そこでlabelに渡されたフォントサイズを反映させてあげればいいのです。 さらにViewController.mのprepareForSegueではDetailViewControllerで定義したfontSizeの値を変更しましょう。 ちなみに、fontSizeはオブジェクトではなくプリミティブな値なので、メモリは自動解放されます。 なので、strongやweakをきにする必要はありません。
  • 21. ここまでのまとめ ・他のオブジェクトの値の変更 ・デバッグ ・nilについて ・強い参照と弱い参照 13年3月17日日曜日 無事に動いたでしょうか。 ここまでのおさらいをします。 まず、他のオブジェクトに対して値を変更する方法を勉強しました。 デバッガの起動方法も触れましたね。nilが何かということも勉強しました。 強い参照と弱い参照にも触れました。 ここでやったことはかなり難しいです。今すぐにすべてを理解するのは大変なので、開発がある程度で切るようになったらも う一度見直していただけるとうれしいです。
  • 22. MVCモデル ここで、他の値も設定するようにプログラムを 変えてみましょう。 数カ所だけならまだしも、何個も変更する値が あるとめんどくさい →そこでMVCモデルを使う 13年3月17日日曜日 今までの話で、画面で設定したものを他の画面へ反映する方法を学んだので、他のパーツを追加し、 変更した値を反映するようにしましょう。 いちいちすべての値を渡すのは大変です。一つのオブジェクトとしてまとめた方が楽です。 そのような要求に応えてくれるのがMVCモデルです。これからMVCモデルについて勉強していきます。 Javaなどでも画面で設定したものをデータオブジェクトに保持するなんてことを行っているかと思います。 Objective-Cでも同じです。iPhoneアプリの開発ではMVCモデルに基づいて開発します。 釈 に説法かも知れないですが、MVCモデルについておさらいします。 Modelでデータの保持およびデータの操作を行います。 ViewでModelのデータを画面に表示します。 Controllerでユーザの操作の受付およびモデルの操作を行います。Viewに対するControllerということでViewControllerを使 っていた訳です。
  • 23. MVCモデル Model データおよびデータの操作 View Controller Modelのデータを ユーザ操作の受付 画面へ表示 モデルの操作 13年3月17日日曜日 Objective-Cでも同じです。iPhoneアプリの開発ではMVCモデルに基づいて開発します。 釈 に説法かも知れないですが、MVCモデルについておさらいします。 Modelでデータの保持およびデータの操作を行います。 ViewでModelのデータを画面に表示します。 Controllerでユーザの操作の受付およびモデルの操作を行います。Viewに対するControllerということでViewControllerを使 っていた訳です。
  • 24. Modelを作成してみよう ・会員(Member)というモデルを作成 ∼モデルのデータ∼ ・会員番号   変数名:memberId 型:int型 ・会員名  変数名:memberName 型:NSString型 このモデルを実現するオブジェクトを作成するには? 13年3月17日日曜日 ViewとControllerについては既に作成しているので、今度はViewで入力したデータを保持するモデルを作成しましょう。 例えば会員(Member)というモデルを作成する例を考えてみます。 モデルの中身は、int型の会員番号とNSString型の会員名とします。この場合、どのようにオブジェクトを作成するにはどう したらいいでしょうか。
  • 25. Modelを作成してみよう 必要なもの ・.hファイル(Model.h) ・.mファイル (Model.m) ・.hファイルの中身 @property(nonatomic,strong) NSString *memberName; @property(nonatomic)int memberId; 13年3月17日日曜日 必要なものは.hファイルと.mファイルです。 メニューのFile→New→Fileを選んで新しいファイルを作成します。 Objective-C Classを選択して次に進んでください。 ClassにはMember、SubClassにはNSObjectを記載して保存してください。 そうすると、Model.hとModel.mが作成されます。Model.hにmemberNameとmemberIdを宣言してください。 @propertyをつけるとgetterとsetterが作成されるので、特にModel.mの記載はいりません。
  • 26. シングルトン どこからでもアクセスできるシングルトンにします。 ・Model.hに以下の記載を追加 +(Member *)sharedInstance; ・Model.mに以下の記載を追加 static Member *member = nil; @implementation Member +(Member *)sharedInstance{ if (member == nil) { member = [[super alloc]init]; } return member; } 13年3月17日日曜日 このままでもいいのですが、どこからでもアクセスできるようにシングルトンにします。 (データを外部ファイルに保存していないので) Model.hには以下のように記載してください。 +(Member *)sharedInstance;+というのは、クラスメソッドであるということです。 つまり、オブジェクトではなく、クラスに対してメッセージを送るということです。 ここではMemberというクラスに対してsharedInstanceというメッセージを送るとMemberがたのオブジェクトが返ってき ます。 Model.mファイルにはsharedInstanceメソッドの実装を行います。 まず、staticをつけることにより、ファイル内だけで有効となります。(ほかのオブジェクトからアクセスできないようにな ります) そして sharedInstanceが呼ばれたときは、nilであるかどうかチェックをして、nilだった場合のみ初期化します。
  • 27. 値の参照方法 値を参照するには以下のように記述します [Member sharedInstance]. memberName; これでMember型のオブジェ クトを取得 取得した値を表示させてみましょう 13年3月17日日曜日 Member型のオブジェクトに設定した値を参照するには [Member sharedInstance]を使ってオブジェクトを取得します。 取得したオブジェクトの値を参照してください。 MVCTestというプロジェクトをに詳細のコードを記載しておりますので、見てみましょう。
  • 28. 一定時間ごとに処理を行う NSTimerを使うと一定間隔で同じメソッドを呼び 出すことが出来る [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(increment:) userInfo:nil タイマーを初期化して開始す repeats:YES]; るメソッド [timer invalidate]; タイマーを止めるメソッド [timer fire]; タイマーを開始するメソッド 13年3月17日日曜日 ここで前回リクエストがあったので、「一定時間ごとに値が更新されるプログラム」について説明をします。NSTimerという クラスを使うと、一定時間間隔で同じメソッドを呼び出すことが出来ます。 お渡ししたファイルにNSTimerTestというプロジェクトがありますので、そちらをご覧ください。
  • 29. 一定時間ごとに処理を行う @selectorって何?? →コンパイラに「この引数はメソッドである(SEL 型)」ことを示すもの [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(increment:) userInfo:nil repeats:YES]; incrementというメソッドを 渡している 13年3月17日日曜日 ここで@selectorについて少し解説します。 @selectorとはコンパイラに対して「この引数はメソッド(関数)である」ということを教えています。 SEL型と言います。ここで使用しているNSTimerでは自分自身のメソッドを繰り返し呼び出しています。
  • 30. 今日のまとめ ・他のオブジェクトの値の変更 ・MVCモデル ・タイマーの使い方 13年3月17日日曜日 では、今日の課題に入る前におさらいをしましょう 最初に他のオブジェクトの値の変更する方法を勉強しました。 そして、MVCモデルを使って色々な画面から値を参照できるようにしました。 おまけにタイマーの使い方を勉強しました。