Start Developing iOS Apps Today(sup.5)〜コードとフレームワークの統合

2012. 12. 18
iOSまたはOS Xのアプリを開発する場合、独力で行うことはできません。
Appleなどによって開発され、Objective-Cフレームワークに集積されたクラスを利用することになります。
フレームワークは実行時に複数の工程で共有することができるクラスライブラリで、ライブラリを使用してソフトウェア開発をサポートするリソースが含まれています。
CocoaとCocoa Touchフレームワークは、貴方のアプリの一部(多くの場合、重要な部分)を構築するために一緒に作用する相互依存のクラスのセットを提供します。

含まれているC関数のライブラリは、貴方が記述しようとするプログラムで関数を使用して呼び出す際に、必要に応じて精選して使用することができます。
一方フレームワークは、貴方のプログラムに設計を課したり、少なくとも特定の問題空間上で貴方のプログラムが対処することになります。
オブジェクト指向フレームワークを使用する場合、手続き型プログラムにおけるように、多くのプログラムの処理を行うため、フレームワークのクラスのメソッドを呼び出すことができます。
ただし汎用的なフレームワークの動作をカスタマイズしたり、フレームワークが適切な時に呼び出せるようにメソッドを実装することによって対応できるようにする必要があります。
これらの方法はフレームワークによって化せられる構造にコードを導入するフックとなり、貴方のプログラムを特徴付ける動作を増大させます。

以下の項で、フレームワークのコードとアプリケーションのコード間の関係を説明します。



●アプリはイベントによって駆動する

アプリケーションの起動時に何が行われているかを考慮することによって、貴方のコードとフレームワークのコード間の関係について、いくつかの洞察を得ることができます。
基本的にアプリはオブジェクトのコアグループを設定し、それらのオブジェクトに制御を渡します。
プログラムが実行されると次々とオブジェクトが生成されますが、まず必要となるのは最初のタスクを処理するために必要な(つまりコアオブジェクトのネットワークに十分な)構成です。
2つの重要なタスクがあります。
  • アプリの初期ユーザインターフェイスを描画
  • ユーザがユーザインターフェイスを操作した時に受信したイベントの処理
初期ユーザインターフェイスが画面に表示された後、アプリは外部イベントによって駆動されますが、最も重要なのはそれらが(例えば、ボタンをタップするなど)ユーザによって生じることです。
オペレーティングシステムはそのようなイベントを、それらについての情報と一緒にアプリに報告します。
アプリは貴方のコードとフレームワークの両方で構成され、イベントを処理し、それに応じてユーザインターフェイスを更新します。

アプリはイベントを取得して(多くの場合、ユーザインターフェイスの一部を描画することによって)それに応答し、次のイベントのために待機します。
ユーザまたは(タイマーなどの)他のリソースが開始されるまで、取得したイベントを保持します。
アプリが起動した時から終了する時まで、ほとんど全てイベントという形式のユーザのアクションによって駆動します。

イベントを取得して応答するためのメカニズムはメインイベントループです。

アプリオブジェクトとコアオブジェクトの一括りで、一つのオブジェクトとしてメインイベントループを管理する(イベントを取得し、そのオブジェクトまたはそれを処理することができる最適なオブジェクトへイベントをディスパッチし、それから次のイベントを取得する)責任があります。
iOSでのCocoa Touchアプリのメインイベントループを下図に示します。

main_event_loop_2x.png



●オブジェクト指向フレームワークの使用

CocoaとCocoa Touchフレームワークは、個々のサービスを提供するクラスの福袋以上のものです。
これらのオブジェクト指向フレームワークは、構造問題空間と統合されたソリューションを提示するクラスのコレクションです。
(関数ライブラリのように)必要に応じて使用できる個別のサービスを提供する代わりに、フレームワークはアプリケーション全体の構造を計画し実装するため、貴方の独自のコードはそれに適応させる必要があります。
アプリケーション構造は汎用的なものであるため、貴方のアプリ特有の要件を満たすように特化させることができます。
むしろアプリにライブラリ関数を挿入する設計はなく、フレームワークによって提供される設計に貴方のアプリのコードを挿入する形となります。

フレームワークを使用するには、定義されているアプリケーション構造を受け入れて採用する必要があり、必要に応じてアプリ特有の構造に整形するために、多くのクラスをカスタマイズします。
フレームワークのクラスはグループとして相互に依存しており、個々に独立してはいません。
一見すると、アプリ用のフレームワークの構造に貴方のコードを適応させる必要性は限定的に見えるかもしれません。
しかし実際には全く逆です。
フレームワークは汎用的な動作を変更および拡張することができる多くの方法を提供します。
それらは全て同じ構造に基づいているため、同じ基本的な方法で全てのアプリが動作するように適応させることを要求します。

広義に例えるならObjective-Cフレームワークは家の骨組みのようなもので、貴方のアプリのコードは独自の家を造るための戸や窓、羽目板などの要素のようなものです。

house_framework_2x.jpg

フレームワークを使用して貴方のコードと統合するという視点で見た場合、2つの一般的なクラスの種類があります。
  • 既製品
    いくつかのクラスが定義する既製品オブジェクト、つまり使用する準備ができているオブジェクトです。
    貴方は単にクラスのインスタンスを生成し、必要に応じてインスタンスを使用します。

  • 汎用品
    汎用的なフレームワークのクラスで、(いくつかの状況では必然的に)それらのサブクラスを生成し、特定のメソッドの実装をオーバーライドすることができます。
    サブクラス化することによって、アプリケーション構造に貴方のコードを導入します。
    フレームワークは適切な機会にサブクラスのメソッドを呼び出します。
汎用的なフレームワークのクラスのサブクラス化は、フレームワークによって提供された構造に貴方のプログラム固有のコードを統合する主要な手法です。
これは唯一の技術ではありませんが、それ以外は多くの場合は好ましい技術ではありません。
以降の記事で学びますが、Cocoa TouchとCocoaフレームワークはアーキテクチャとメカニズムを含み、全ての設計パターンの基礎であり、双方のフレームワークオブジェクトと貴方のカスタムオブジェクト間で、重要な協調と調整を可能にします。

サブクラスを作成する場合、どのクラス(スーパークラス)から継承するかと、そのクラスのどのメソッドをオーバーライドするかという、2つの基本的な決定する事項があります。
以下の項では、これらの決定を行うための状況を説明します。



●CocoaまたはCocoa Touchクラスからの継承

UIKitなどのフレームワークは構造を定義していますが、一般的なものであるため多くのアプリの種類は共有することができます。
構造は一般的なものであるため、いくつかのフレームワーククラスは抽象的または意図的に不完全ですが、驚くべきことではありません。
このようなクラスは多くの場合、共通するコードのかなりの量を実装しますが、安全なデフォルトの方法で元に戻すか完了し、処理の重要な部分は残します。

フレームワークにアプリケーション固有の動作を追加する主な方法は、これらのフレームワークのいずれかのクラスのカスタムサブクラスを生成することです。
サブクラスはフレームワークのクラスで欠けている部分を供給し、これらのスーパークラスの不足を補充します。
貴方のカスタムサブクラスのインスタンスは、フレームワークが定義するオブジェクトのネットワーク上での役割を引き継ぎ、フレームワークから他のオブジェクトと処理を行う能力を継承します。
アプリで有用な何かを行うためには、少なくとも1つ、できれば多くのサブクラスを生成する必要があります。

以降の解説ではサブクラス化するための計画と解決についての説明と、いくつかの一般的な要件を述べています。
どのようにサブクラスを作成するかについての詳細は含まれていません。
その技術は『Objective-Cプログラミング言語』の『クラスの定義』で説明されています。


サブクラスを作成する際

サブクラス化は既存のクラスを再利用する工程で、貴方の必要とするものに特殊化します。
時には全てのサブクラスが単一継承されたメソッドをオーバーライドする必要があり、メソッドは元の動作とは若干異なる何かを持っています。
他のサブクラスはスーパークラスに(インスタンス変数などの)属性を1つまたは2つ追加するなどして、その後これらの属性へアクセスしたり操作するメソッドを定義し、スーパークラスの動作に統合します。

サブクラス化は、サブクラスにフレームワークのクラスを識別させることから始まります。
ここで貴方を導くためのいくつかの考慮事項があります。

  • フレームワークを知る

    貴方はフレームワークの各クラスの目的と機能を理解する必要があります。
    始めるには、デベロッパライブラリのフレームワークの導入を読み、フレームワークのクラスのリストを調べます。
    多分、貴方が必要とするクラスは既にあると思います。
    貴方が必要とするクラスがほとんど見つけられたら、あなたは幸運です。
    そのクラスは貴方のカスタムクラスのための有望なスーパークラスです。

    例えば『初めてのiOSアプリケーション』での処理の場合、UIViewControllerとUIKitフレームワークのその他のクラスに遭遇しました。
    これらのクラスについて詳細を調べるには、以下の事を行います。

    1. XcodeでWindowメニューのOrganizerを選択します。
    2. ツールバーのDocumentaionボタンをクリックします。
    3. インストール済みのデベロッパライブラリの閲覧を始めるには、ナビゲーション領域の上部にあるBrowse(Explore Documentation)をクリックします。
    4. 最新のiOSライブラリをクリックします(最初にApple Developerにログインする必要があるかもしれません)。
      コンテンツ領域にiOS Developer Libraryが開きます。
    5. ドキュメント領域のドキュメントのリスト上部にあるドキュメントフィルタフィールドに、『UIKit Framework Reference』と入力します。
      フィルタリングされたリストには、入力したドキュメントの名前だけが表示されます。
    6. UIKitの全てのクラスとプロトコルを表示するページを開くため、ドキュメント名をクリックします。

    導入を読み、それらについてもっと学ぶため、リストされたクラスまたはプロトコルをクリックします。

  • アプリが何を行うのかが非常に明確である

    この助言は全体としてのアプリとアプリの特定の部分に適用されます。
    いくつかのフレームワークのアーキテクチャは、独自のサブクラス化の要件を課します。
    例えば貴方のアプリがドキュメントベースの場合、抽象ドキュメントクラスのサブクラスである必要があります。

  • サブクラスのインスタンスが果たす役割を定義する

    iOSまたはOS X用のアプリ開発では、モデル-ビュー-コントローラのデザインパターンがオブジェクトに役割を割り当てるために使用されています。
    ビューオブジェクトはユーザインターフェイスを表示し、モデルオブジェクトはアプリケーションのデータを保持し(そしてデータを決定するアルゴリズムを実装して)、コントローラオブジェクトはビューとモデルオブジェクト間の仲介を行います。
    オブジェクトが果たす役割を知ることで、どのスーパークラスを使用するかの決定を絞り込むことができます。
    例えばiOSアプリでカスタム描画を行いたい場合、UIKitフレームワークのビュークラスを元にして、UIViewのサブクラスを使うことになるかもしれません。

iOSとOS Xのプログラミングにおいて重要ではありますが、時にはサブクラス化は問題を解決する最善の方法ではありません。
便利なメソッドを少し追加するだけの場合、サブクラスの代わりにカテゴリを生成する場合もあります。
またはアプリケーション固有の動作を挿入するには、デリゲートなどのデザインパターンを元にした、フレームワークの多くの他のリソースのいずれかを使うこともできます。
(これらのパターンはデザインパターンの記事『Streamline Your App with Design Patterns』に記述されています。)
そして、いくつかのフレームワークのクラスはサブクラス化を意図していないことを心に留めておいてください。
リファレンスドキュメントでは、フレームワークのクラスがサブクラス化されることを意図しているかが説明されています。


メソッドのオーバーライド

任意のスーパークラスのメソッドを再実装せずにサブクラスを生成することも可能です。
例えばサブクラスに特別な状態を追加したり、状態にアクセスする新しいメソッドを定義したり、スーパークラスのメソッドを呼び出すこともできます。
ただし、いくつかのサブクラスの主なタスクは、スーパークラス(またはスーパークラスによって採用されたプロトコル)によって宣言されたメソッドの独自の設定を実装することです。
継承されたメソッドの再実装はメソッドのオーバーライドとして知られています。

フレームワークのクラスで定義されているほとんどのメソッドは実装済みであり、クラスが提供するサービスを得るために呼び出すことができます。
そのようなメソッドはオーバーライドする必要は稀なので、オーバーライドしようとしないでください。
その他のフレームワークのメソッドはオーバーライドすることができますが、そうする理由は滅多にありません。

いくつかのフレームワークのメソッドはオーバーライドされることを意図していますが、フレームワークにプログラム固有の動作を追加できるように存在しています。
多くの場合、フレームワークによって実装されているメソッドは貴方のアプリにとって価値はほとんど、あるいは全くありません。
これらのメソッドの種類のコンテンツを提供するため、アプリは独自のバージョンを実装する必要があります。
フレームワークはアプリの実行中の適切な時期にこれらのメソッドを呼び出します。


呼び出しまたはオーバーライド?

サブクラスでオーバーライドするフレームワークのメソッドは、一般的に貴方が自身を呼び出すメソッドではなく、少なくとも直接ではありません。
貴方は単にメソッドを再実装し、後はフレームワークに任せます。
実際には、アプリケーション固有のバージョンのメソッドを記述することになり、貴方の独自のコードで呼び出すことはあまりないでしょう。
一般的に、フレームワークのクラスはパブリックメソッドを宣言し、開発者は以下の2つの内1つを実行します。
  • クラスが提供するサービスを使用するために呼び出す。
  • フレームワークによって定義されているプログラムモデルに、独自のコードを取り入れてオーバーライドする。
時にはメソッドがこれら両方の種類であり、呼び出し時に有益なサービスを行い、効果的にオーバーライドすることができます。
しかしほとんどの場合、呼び出すことができるメソッドはフレームワークによって完全に定義されており、コード内で再定義する必要はありません。
メソッドをサブクラスで再実装する必要がある場合、フレームワークはそれを行うための特定の処理を持っているので、適切な時にメソッド自体を呼び出します。
フレームワークのメソッドの一般的な2つのタイプを下図に示します。

message_web_2x.png

この図では貴方のカスタムクラスの架空のメソッド(myMethod)が、フレームワークによって実装されているsetNeedsDisplayメソッドを呼び出します。

フレームワークは描画環境を設定するためにいくつかの処理を行い、その後フレームワークで宣言されていて、実際に描画を行うためにカスタムクラスによってオーバーライドされているメソッドdrawRect:を呼び出します。

メソッドのオーバーライドは困難な作業ではありません。
多くの場合、複数のコードの行を必要とせず、メソッドの再実装を慎重に行うことによって、スーパークラスの動作に重要な変更を行うことができます。


スーパークラスの実装を呼び出す

フレームワークメソッドをオーバーライドする場合、継承されたメソッドの動作を置換するのか、あるいは動作を拡張または追加するのかを決定する必要があります。
既存の動作を置換する場合は単にメソッドを独自に実装して提供し、動作を拡張する場合はスーパークラスの実装を呼び出して独自のコードを提供します。

superのメソッドを呼び出す場合と同じくメッセージを送信することによって、スーパークラスの実装を呼び出します。
superにメッセージを送信することによって、呼び出し時に再実装しているメソッドへスーパークラスのコードが『プラグイン』されます。
例えば架空のCelebrateクラスがperformFireworksという名前のメソッドを定義しているとします。
フレームワークがビューに花火のアニメーションを描画した後、ビューにバナーを表示するとします。
この場合、superがどのように処理を呼び出すかを下図に示します。

calling_super_2x.png

このようにsuperを呼び出すための決定は、どのようにメソッドを再実装しようとしているかに基づいています。
  • スーパークラスの実装の動作を補足するつもりならば、superを呼び出します。
  • スーパークラスの実装の動作を置換するつもりならば、superを呼び出しません。
スーパークラスの動作を補足する場合、他の重要な考慮事項は何時スーパークラスのメソッドの実装を呼び出すかです。
貴方のコードが実行される前にスーパークラスのコードを呼び出したい場合もあれば、逆の場合もあります。



参考文献

Apple/Start Developing iOS Apps Today

Apple/Integrate Your Code with the Frameworks

0 CommentsPosted in 資料





Bose QuietComfort 20
0 Comments
Leave a comment
管理者にだけ表示を許可する
Top
0 Trackbacks
Top
Calendar
08 | 2017/09 | 10
Sun Mon Tue Wed Thu Fri Sat
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Recent Articles
iTunes


Swift
Categories
Tips
Profile

水月杏香

Author:水月杏香
永遠の初心者プログラマ。

Wish List
WACOM


ARC
Technical Q&A
情報プロパティリストキー
Start Developing iOS Apps Today
BOSE

Bose QuietComfort 20
Reference
NSApplicationDelegateプロトコル
NSArrayクラス
NSAutoreleasePoolクラス
NSBundleクラス
NSBundle UIKit追加分
NSCalendarクラス
NSCoderクラス
NSCodingプロトコル
NSCopyingプロトコル
NSDataクラス
NSDateクラス
NSDateFormatterクラス
NSDictionaryクラス
NSEntityDescriptionクラス
NSEnumeratorクラス
NSErrorクラス
NSExceptionクラス
NSFetchRequestクラス
NSFileHandleクラス
NSFileManagerクラス
NSIndexPathクラス
NSIndexPath UIKit追加分
NSKeyedArchiverクラス
NSKeyedUnarchiverクラス
NSKeyValueCodingプロトコル
NSLocaleクラス
NSManagedObjectクラス
NSManagedObjectContextクラス
NSManagedObjectModelクラス
NSMutableArrayクラス
NSMutableCopyingプロトコル
NSMutableDictionaryクラス
NSMutableSetクラス
NSNotificationクラス
NSNotificationCenterクラス
NSNullクラス
NSNumberクラス
NSObjectクラス
NSObject UIKit追加分
NSObjectプロトコル
NSPersistentStoreクラス
NSPersistentStoreCoordinatorクラス
NSPredicateクラス
NSPropertyListSerializationクラス
NSRunLoopクラス
NSSetクラス
NSStringクラス
NSString UIKit追加分
NSTimerクラス
NSTimeZoneクラス
NSURLクラス
NSURLProtectionSpaceクラス
NSURLRequestクラス
NSUserDefaultsクラス
NSValueクラス

UIActionSheetクラス
UIActionSheetDelegateプロトコル
UIActivityIndicatorViewクラス
UIAlertViewクラス
UIAlertViewDelegateプロトコル
UIApplicationクラス
UIApplicationDelegateプロトコル
UIBarButtonItemクラス
UIBarItemクラス
UIButtonクラス
UIColorクラス
UIControlクラス
UIDatePickerクラス
UIDeviceクラス
UIEventクラス
UIFontクラス
UIGestureRecognizerクラス
UIImageクラス
UIImageViewクラス
UIKit Function
UILabelクラス
UINavigationControllerクラス
UINavigationItemクラス
UIPickerViewクラス
UIPickerViewDataSourceプロトコル
UIPickerViewDelegateプロトコル
UIPinchGestureRecognizerクラス
UIResponderクラス
UIScreenクラス
UIScrollViewクラス
UISearchBarクラス
UISearchBarDelegateプロトコル
UISegmentedControlクラス
UISliderクラス
UISwipeGestureRecognizerクラス
UISwitchクラス
UITableViewクラス
UITableViewCellクラス
UITableViewControllerクラス
UITableViewDataSourceプロトコル
UITableViewDelegateプロトコル
UITapGestureRecognizerクラス
UITextFieldクラス
UITextFieldDelegateプロトコル
UITextInputTraitsプロトコル
UITextViewクラス
UITextViewDelegateプロトコル
UIToolbarクラス
UITouchクラス
UIViewクラス
UIViewControllerクラス
UIWebViewクラス
UIWebViewDelegateプロトコル
UIWindowクラス

AVAudioPlayerクラス
AVAudioPlayerDelegateプロトコル

CADisplayLinkクラス
CAEAGLLayerクラス
CALayerクラス

CGAffineTransform
CGBitmapContext
CGColor
CGColorSpace
CGContext
CGGeometry
CGImage
CGPath

EAGLContextクラス
EAGLDrawableプロトコル

Foundation Constants
Foundation Data Types
Foundation Functions

MPMediaItemクラス
MPMediaItemArtworkクラス
MPMediaPlaylistクラス
MPMediaPropertyPredicateクラス
MPMediaQueryクラス
MPMusicPlayerControllerクラス

Randomization Services

System Sound Services
Amazon


OpenGL ES
SQLite
Monthly Archives
Recent Comments
Recent TrackBacks
RSS Link
Visitors
QR Code
QR