Start Developing iOS Apps Today(10)~カスタムクラスの記述

2014. 03. 24
●カスタムクラスの記述

iOSアプリを開発する際、独自のカスタムクラスを記述する必要がある場合には、多くの要因があることを知るでしょう。
カスタムクラスは、データと一緒にカスタム動作をパッケージ化する必要がある場合に有益です。
カスタムクラスでは、データの保存、操作、そして表示するための独自の動作を定義することができます。

例えば、iOSのClockアプリでのWorld Clockタブを考えてみます。
このテーブルビューのセルは、標準のテーブルビューセルよりも多くのコンテンツを表示する必要があります。
これは指定したテーブルビューセル用に追加のカスタムデータを表示できるように、UITableViewCellの動作を拡張するサブクラスを実装するための良い機会です。
このカスタムクラスを設計していた場合、時差情報を表示するためのラベルのアウトレットと、セルの右側にカスタム時計を表示するためのイメージビューを追加するでしょう。

custom_class_2x.png

この章ではToDoListアプリの動作の実装を完了するため、Objective-Cの構文とクラスの構造について知っておくべきことを教えます。
すなわちToDoリスト上の単一項目を表すカスタムクラスであるXYZToDoItemの設計について説明します。
3つ目のチュートリアルでは、実際にこのクラスを実装してアプリに追加します。



●クラスの宣言と実装

Objective-Cのクラスの仕様では、インターフェイスと実装の2つの別個な部品を必要とします。
インターフェイスは、オブジェクトの型を他のオブジェクトによって使用されることを意図して、正確に指定します。
言い換えると、クラスのインスタンスと外界との間のパブリックインターフェイスを定義します。
実装は、インターフェイスで宣言された各メソッドの実行可能なコードが含まれています。

オブジェクトは内部実装の詳細を隠すように設計する必要があります。
Objective-Cではインターフェイスのみを公開する必要があるため、通常はインターフェイスと実装を別々のファイルに置きます。
Cコードと同様に、コードの実装の詳細からパブリック宣言を分離するため、ヘッダファイルとソースファイルを定義します。
インターフェイスファイルは.h拡張子を持ち、実装ファイルは.m拡張子を持っています。
(この後「チュートリアル:データの追加」で部品の全てに導入されるように、今のXYZToDoItemクラス用にこれらのファイルを作成します。)


インターフェイス

Objective-Cでクラスのインターフェイスを宣言する構文は、以下のようになります。

@interface XYZToDoItem : NSObject

@end

この例では、NSObjectから継承したXYZToDoItemという名前のクラスを宣言しています。

パブリックなプロパティと動作は@interface宣言の内側で定義されています。
この例では、スーパークラス以降に何も指定されていないので、XYZToDoItemのインスタンスで利用可能と想定される動作のみがNSObjectから継承された動作になります。
全てのオブジェクトは最小限の動作を有する事を求められるため、デフォルドではNSObject(またはそのサブクラスの一つ)から継承する必要があります。


実装

Objective-Cでクラスの実装を宣言する構文は、以下のようになります。

#import "XYZToDoItem.h"

@implementation XYZToDoItem

@end

クラスのインターフェイスで何らかのメソッドを宣言する場合、このファイル内で実装する必要があります。



●プロパティはオブジェクトのデータを格納する

保持する必要のあるToDo項目の情報を検討します。
おそらくそれを作成した時の名前や、それが完了したかどうかが必要となります。
カスタムXYZToDoItemクラスでは、プロパティにこの情報を格納します。

これらのプロパティの宣言は、インターフェイスファイル(XYZToDoItem.h)内に存在します。
ここでは以下のようにします。

@interface XYZToDoItem : NSObject

@property NSString *itemName;
@property BOOL completed;
@property NSDate *creationDate;

@end

この例では、XYZToDoItemクラスは3つのパブリックプロパティを宣言しています。
これらのプロパティは、完全なパブリックアクセスのために用意されています。
パブリックアクセスでは、他のオブジェクトがプロパティ値の読み込みと変更の両方を行う事ができます。

貴方はプロパティが変更されてはならない(つまり読み込みのみ)と宣言を決定する事ができます。
プロパティが(特に)読み込みのみであることを意図しているかどうかを示すために、Objective-Cのプロパティ宣言にはプロパティ属性が含まれています。
例えばXYZToDoItemの作成日を変更可能にしたくない場合は、以下のようにXYZToDoItemクラスのインターフェイスを更新します。

@interface XYZToDoItem : NSObject

@property NSString *itemName;
@property BOOL completed;
@property (readonly) NSDate *creationDate;

@end

プロパティはプライベートまたはパブリックにすることができます。
時には他のクラスから参照やアクセスができないように、プロパティをプライベートにした方が良いこともあります。
例えば完了したと印された項目の日付を表すプロパティの追跡を、他のクラスにこの情報へのアクセスを与えずに維持したい場合、実装ファイル(XYZToDoItem.m)の先頭にクラス拡張でそれを置く事によってプロパティをプライベートにすることができます。

#import "XYZToDoItem.h"

@interface XYZToDoItem ()
@property NSDate *completionDate;
@end

@implementation XYZToDoItem

@end

プロパティへのアクセスにはゲッタセッタを使用します。
ゲッタはプロパティの値を返し、セッタはそれを変更します。
ゲッタとセッタにアクセスするための一般的な構文的短縮形はドット表記です。
読み込みと書き込みのアクセスができるプロパティは、プロパティ値の取得と設定の両方にドット表記を使用することができます。
クラスXYZToDoItemのオブジェクトtoDoItemがある場合、以下の操作を行うことができます。

toDoItem.itemName = @"Buy milk";    // itemNameの値の設定
NSString *selectedItemName = toDoItem.itemName;    // itemNameの値の取得



●オブジェクトの動作をメソッドで定義

メソッドは、オブジェクトが何ができるかを定義します。
メソッドは、クラス内のタスクまたはサブルーチンを実行するために定義するコードの一部です。
メソッドはクラス内に格納されているデータにアクセスすることができ、何らかの操作を実行するためにその情報を使用することができます。

例えば、ToDo項目(XYZToDoItem)に完了したと印されたものを取得する機能を提供するには、クラスインターフェイスにmarkAsCompletedメソッドを追加することができます。
クラスの実装でこのメソッドの動作を実装する方法については、後ほど「メソッドの実装」で説明します。

@interface XYZToDoItem : NSObject

@property NSString *itemName;
@property BOOL completed;
@property (readonly) NSDate *creationDate;
- (void)markAsCompleted;

@end

メソッド名の前にあるマイナス記号(-)はインスタンスメソッドであることを示し、そのクラスのオブジェクト上で呼び出すことができます。
このマイナス記号は、プラス記号(+)で示されるクラスメソッドと区別するものです。
クラスメソッドはクラス自体で呼び出すことができます。
クラスメソッドの一般的な例は、「Foundationでの処理」で学んだクラスファクトリメソッドです。
またクラスに関連付けられた共有情報のいくつかの部分にアクセスするために、クラスメソッドを使用することができます。

voidキーワードはメソッドが値を返さないことを示すために、宣言の文頭で丸括弧内で使用されます。
この場合、markAsCompletedメソッドはパラメータを取り込みません。
パラメータは「メソッドのパラメータ」で詳細を説明します。



メソッドのパラメータ

メソッドを呼び出す時に、情報のいくつかの部品に渡すためのパラメータと共にメソッドを宣言します。

例えば、項目が完了または未了と印されているかどうかを決定する単一のパラメータを取得するために、以前のコードの断片からmarkAsCompletedメソッドを修正することができます。
以下のように項目を完了済みとしてのみ設定していた代わりに、完了状態を切り替えることができます。

@interface XYZToDoItem : NSObject

@property NSString *itemName;
@property BOOL completed;
@property (readonly) NSDate *creationDate;
- (void)markAsCompleted:(BOOL)isComplete;

@end

ここでメソッドはisCompleteとというBOOL型のパラメータを一つ取ります。

名前でパラメータを指定してメソッドを参照する時は、メソッド名の一部としてコロンを含めるため、更新されたメソッド名は現在markAsCompleted:となっています。
メソッドが複数のパラメータを持っている場合、メソッド名は分割されてパラメータ名が点在します。
このメソッドに別のパラメータを追加したい場合は、次のように宣言します。

- (void)markAsCompleted:(BOOL)isComplete onDate:(NSDate *)date;

ここではメソッド名をmarkAsCompleted:onDate:と記述しています。
isCompleteとdateという名前は、これらの名前が変数であるとした場合、メソッドが呼び出された時に提供された値にアクセスするために実装で使用されています。



メソッドの実装

メソッドの実装は、関連するコードを含めるために中括弧を使用します。
メソッド名はインターフェイスファイル内で対応するものと同一である必要があり、パラメータや戻り値の型も厳密に一致する必要があります。

XYZToDoItemクラスインターフェイスに追加される、markAsCompleted:メソッドの単純な実装は以下の通りです。

@implementation XYZToDoItem
- (void)markAsCompleted:(BOOL)isComplete {
    self.completed = isComplete;
}
@end

プロパティと同様に、メソッドもプライベートまたはパブリックにすることができます。
パブリックメソッドはパブリックインターフェイスで宣言され、他のオブジェクトから見たり呼び出したりすることができます。
これらに対応する実装は実装ファイルに在り、他のオブジェクトから見ることはできません。
プライベートメソッドはクラス内部にのみ実装を持ち、これはクラスの実装の内部でのみ呼び出して利用することができることを意味します。
これは他のオブジェクトからのアクセスを排除し、クラスの内部動作を追加するための強力なメカニズムです。

例えば、更新されたToDo項目のcompletionDateを維持したいとします。
ToDo項目が完了したと印されていた場合、completionDateを現在に日時に設定します。
未了であると印されていた場合、まだ完了していないのでcompletionDateをnilに設定します。

ToDo項目のcompletionDateの更新は自己完結型のタスクであるため、ベストプラクティスは独自のメソッドを記述することです。
ただし他のオブジェクトがこのメソッド呼び出すことできないことを確認することが重要で、そうしないと他のオブジェクトがいつでもToDo項目のcompletionDateを設定することができてしまいます。
このような理由から、このメソッドをプライベートにします。

それでは完了または未了と印されたことを取得する毎に、ToDo項目のcompletionDateを更新するために内部でmarkAsCompleted:を呼び出す、プライベートメソッドのsetCompletionDateを含めるためにXYZToDoItemの実装を更新します。
他のオブジェクトにこのメソッドを見せたくないので、インターフェイスファイルには何も追加しないことに注意してください。

@implementation XYZToDoItem

- (void)markAsCompleted:(BOOL)isComplete {
    self.completed = isComplete;
    [self setCompletionDate];
}

- (void)setCompletionDate {
    if (self.completed) {
        self.completionDate = [NSDate date];
    } else {
        self.completionDate = nil;
    }
}

@end

ここで、XYZToDoItemクラスを使用してToDoリスト項目の基本的な表現を定義しました。
XYZToDoItemはプロパティの形式で自身についての情報(名前、作成日時、完了状態)を格納し、メソッドを使用して何ができるか(完了または未了との印の取得)を定義します。
これは次のチュートリアルでToDoListアプリの実装を完了するために必要な機能の範囲です。
ただし貴方は常にアプリに新しい動作を統合するために、クラスに独自のプロパティやメソッドを追加して試すことができます。



参考文献

Apple/Start Developing iOS Apps Today

0 CommentsPosted in 資料





Bose SoundSport wireless headphones
0 Comments
Leave a comment
管理者にだけ表示を許可する
Top
0 Trackbacks
Top
Calendar
02 | 2017/03 | 03
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 31 -
Recent Articles
iTunes


Swift
Categories
Tips
WACOM


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
BOSE

Bose SoundSport wireless headphones
ARC
Technical Q&A
情報プロパティリストキー
Start Developing iOS Apps Today
SQLite
OpenGL ES
Amazon


Monthly Archives
Recent Comments
Recent TrackBacks
RSS Link
Profile

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

QR Code
QR
Visitors