iPhoneアプリ開発講習会 第4回 Foundationフレームワーク Copyright © 2012 Kazumasa Kojima All Rights Reserved. 前回の講義 Objective-C【後編】 • メモリ管理 • アウトレット • プロトコル • プロパティ • セレクター • 【参考】カテゴリー/エクステンション 2 今回の講義 Foundationフレームワーク • Cocoa Touchフレームワーク • Foundationフレームワーク • 文字列 • コレクション • 【参考】通知 3 Cocoa Touchフレームワーク Cocoa Touchフレームワーク Cocoa Touchフレームワークとは? • iOSアプリ開発のために提供されているプログラ ムの部品群 • • クラス、関数、型、定数 など 大部分がObjective-Cによって実装 • 多くのフレームワークから構成 • Foundation、UIKit、Core Animation、Core Data など 5 Cocoa Touchフレームワーク Foundationフレームワークとは? • アプリの基盤となる部品群から構成されている フレームワーク • • Mac OS X向けのアプリ開発でも利用 • NSObject、文字列、コレクション、データ、通信の ためのクラス など 部品の名前は「NS」から始まる 6 Cocoa Touchフレームワーク UIKitフレームワークとは? • iOS向けGUIアプリ開発のために提供されている フレームワーク • 部品の名前は「UI」から始まる • GUI部品(ラベル、ボタンなど)、アプリそのものを 表すクラス など ➡ 詳細は次回以降の講義にて 7 Foundationフレームワーク Foundationフレームワーク Immutable(不変) と Mutable(可変) クラス • インスタンス作成後のデータ変更(追加、編 集、削除)の可否 • 可変なクラスは必要時にサイズが自動で拡大 • 一般的な規則 • 可変なクラスの名前にはMutableが含まれる • 可変なクラスは不変なクラスのサブクラス ex. NSString(不変) / NSMutableString(可変) 9 Foundationフレームワーク • 目的に応じて使い分け • Immutableクラス:データの変更がない、データを 変更されると不都合な場合 • Mutableクラス:データを変更して使用、データを 変更されることが前提の場合 10 Foundationフレームワーク Foundationフレームワーク利用上の注意点 • NSObject以外のクラスのサブクラス化は可能 だが、一般的にしない 11 文字列 文字列 文字列クラス • 文字列(String)データを扱うためのクラス ‣ NSString • 不変な文字列データを扱うクラス ‣ NSMutableString • 可変な文字列データを扱うクラス • NSStringのサブクラス 13 NSString 主なメソッドと使用例 ▽ インスタンスの作成と初期化(1/3) ‣ - (id)init ‣ + (id)string • 空の文字列を作成 • 後者はコンビニエンスコンストラクタ NSString *string1 = [[NSString alloc] init]; NSString *string2 = [NSString string]; // クラスメソッド 14 NSString 【参考】コンビニエンスコンストラクタ • 一時的に利用するためだけのオブジェクトを 作成するためのクラスメソッド • 不変なクラス名の接頭語を除いたものから メソッドの名前が始まる ex. NSString string... • alloc + init + autoreleaseしたものに相当 ➡ 所有が発生しない 15 NSString ▽ インスタンスの作成と初期化(2/3) ‣ - (id)initWithString:(NSString *)aString ‣ + (id)stringWithString:(NSString *)aString • 文字列から文字列を作成 • aStringへのnilの指定は不可 NSString *string1 = [[NSString alloc] initWithString:@"Name"]; NSString *string2 = [NSString stringWithString:string1]; 16 NSString ▽ インスタンスの作成と初期化(3/3) ‣ - (id)initWithFormat:(NSString *)format, ... ‣ + (id)stringWithFormat:(NSString *)format, ... • printf()関数と同様に書式文字列と対応する変数(また は定数)を指定して文字列を作成 • formatへのnilの指定は不可 float value1 = 3.0; float value2 = 2.1; NSString *string1 = [[NSString alloc] initWithWithFormat:@"Value1:%f Value2:%f", value1, value2]; 17 NSString ▽ 長さ ‣ - (NSUInteger)length • 文字列に含まれる文字数を返す NSString *string = [NSString string]; NSUInteger stringLength = [string length]; // 0 NSUInteger constantStringLength = [@"Name" length]; // 4 18 NSString ▽ 検索 ‣ - (NSRange)rangeOfString:(NSString *)aString • 文字列に最初に現れるaStringの範囲を返す • aStringへのnilの指定は不可 • NSRange:(NSUInteger location, NSUInteger length)の構造体 • 見つからない場合には(NSNotFound, 0) NSString *string = @"ABCAAABC"; NSRange range1 = [string rangeOfString:@"ABC"]; // (0, 3) NSRange range2 = [string rangeOfString:@"D"]; // (NSNotFound, 0) 19 NSString ▽ 比較 ‣ - (NSComparisonResult)compare:(NSString *)aString • ReceiverとaString(nilは不可)の文字列を比較し、辞 書的な前後関係を結果として返す • NSComparisonResult • NSOrderedSame (0): Receiver = aString • NSOrderedAscending (-1): Receiver < aString • NSOrderedDescending (1): Receiver > aString [@"A" compare:@"B"]; // NSOrderedAscending [@"B" compare:@"A"]; // NSOrderedDescending 20 NSString ▽ 結合 ‣ - (NSString *)stringByAppendingFormat:(NSString *)format, ... • 書式文字列を追加し、新しい文字列を返す • formatへのnilの指定は不可 NSUInteger value = 10; NSString *appendedString = [@"ABC" stringByAppendingFormat:@":%d %@", value, @"kg"]; // ABC: 10 kg 21 NSString ▽ 置換 ‣ -(NSString*)stringByReplacingOccurrencesOfString: (NSString *)target withString:(NSString *)replacement • 文字列中に含まれる全てのtargetをreplacementに 置換 • 置換した文字列を返す NSString *replacedString = [@"AABBCC" stringByReplacingOccurrencesOfString:@"A" withString:@"ZZ"]; // ZZZZBBCC 22 NSMutableString 主なメソッドと使用例 ▽ インスタンスの作成と初期化 ‣ - (id)initWithCapacity:(NSUInteger)capacity ‣ + (id)stringWithCapacity:(NSUInteger)capacity • capacityで指定した長さの文字列を格納可能なインス タンスを作成して返す ➡ 実行効率の向上のため ➡ 後から指定した以上の長さになっても問題ない NSMutableString *mutableString = [NSMutableString stringWithCapacity:3]; 23 NSMutableString ▽ 結合 ‣ - (void)appendFormat:(NSString *)format, ... • 書式文字列を既存の文字列に追加する • formatへのnilの指定は不可 ➡ NSStringのstringByAppendingFormat:メソッド とは異なり、Receiverのデータ自体が更新される NSMutableString *mutableString = [[NSMutableString alloc] initWithString:@"AAA"]; [mutableString appendString:@": %d", 10]; // AAA: 10 24 NSMutableString ▽ 置換 ‣ - (void)setString:(NSString *)aString • Receiverの文字列をaStringに置換 • aStringへのnilの指定は不可 NSMutableString *mutableString = [NSMutableString stringWithCapacity:3]; [mutableString setString:@"AAA"]; // AAA [mutableString setString:@"BBBBB"]; // BBBBB 25 コレクション コレクション コレクションとは? • オブジェクトの集まりを格納するクラス ➡ オブジェクト以外の格納は不可(nilも不可) ➡ 格納されたオブジェクトはコレクションが所有 ➡ コレクションの解放時にオブジェクトはコレクション によって所有を放棄される • 主なクラス • 配列 • 辞書 • 集合 ※講義では扱わない 27 配列 配列とは? • オブジェクトを順番に格納するコレクション • 格納場所はインデックスで指定 ‣ NSArray • 不変な配列を扱うクラス ‣ NSMutableArray • • 可変な配列を扱うクラス NSArrayのサブクラス 28 NSArray 主なメソッドと使用例 ▽ インスタンスの作成と初期化(1/2) ‣ - (id)initWithObjects:(id)firstObj, ... ‣ + (id)arrayWithObjects:(id)firstObj, ... • 引数で指定した可変個のオブジェクトを格納した配列 を作成して返す • 引数はコンマで区切り、最後に必ずnilを指定 ➡ nilは最後尾を表す目印で配列には格納されない 29 NSArray ▽ インスタンスの作成と初期化(2/2) NSString *string1 = [[NSString alloc] initWithString:@"X"]; NSString *string2 = @"Y"; NSObject *object = [[NSObject alloc] init]; NSArray *array = [[NSArray alloc] initWithObjects:string1, string2, object, nil]; // 配列によって所有されたので所有を放棄してもいい [string1 release]; [object release]; 30 NSArray ▽ サイズ ‣ - (NSUInteger)count • 配列に格納されているオブジェクトの個数を返す NSArray *array = [NSArray arrayWithObjects:@"A", @"B", nil]; NSUInteger count = [array count]; // 2 31 NSArray ▽ オブジェクトの取得 ‣ - (id)objectAtIndex:(NSUInteger)index • indexに格納されたオブジェクトを取得 • 最後尾のインデックスを超えた値の指定は不可 NSArray *array = [NSArray arrayWithObjects:@"A", @"B", @"C", nil]; id object = [array objectAtIndex:0]; // A object = [array objectAtIndex:2]; // C object = [array objectAtIndex:3]; // エラー 32 NSArray ▽ ソート ‣ - (NSArray *)sortedArrayUsingSelector:(SEL)comparator • 配列内のオブジェクトをcomparatorで昇順にソート して返す • comparatorには、2つのオブジェクトを比較し、 NSComparisonResultを返すメソッドのセレクター を指定 NSArray *array = [NSArray arrayWithObjects:@"B", @"A", @"C", nil]; NSArray *sortedArray = [array sortedArrayUsingSelector:@selector(compare:)]; // A, B, C 33 NSMutableArray 主なメソッドと使用例 ▽ インスタンスの作成と初期化(1/2) ‣ - (id)init; ‣ + (id)array; • 空の配列を作成して返す NSMutableArray *mutableArray1 = [[NSMutableArray alloc] init]; NSMutableArray *mutableArray2 = [NSMutableArray array]; 34 NSMutableArray ▽ インスタンスの作成と初期化(2/2) ‣ - (id)initWithCapacity:(NSUInteger)numItems ‣ + (id)arrayWithCapacity:(NSUInteger)numItems • numItemsで指定した個数のオブジェクトを格納する のに十分なメモリを割り当てた配列を作成して返す ➡ 後からこのサイズを超えても問題ない NSMutableArray *mArray = [NSMutableArray arrayWithCapacity:3]; 35 NSMutableArray ▽ オブジェクトの追加 ‣ - (void)addObject:(id)anObject • anObjectを配列の末尾に追加する • anObjectへのnilの指定は不可 NSMutableArray *mArray = [NSMutableArray arrayWithCapacity:3]; [mArray addObject:@"A"]; // A [mArray addObject:@"B"]; // A, B [mArray addObject:@"C"]; // A, B, C 36 NSMutableArray ▽ オブジェクトの削除 ‣ - (void)removeObjectAtIndex:(NSUInteger)index • indexに格納されているオブジェクトを削除 • 最後尾のインデックスを超えた値の指定は不可 ‣ - (void)removeAllObjects • 配列内の全てのオブジェクトを削除 NSMutableArray *mArray = [[NSMutableArray alloc] initWithObject:@"A", @"B", @"C", @"D", nil]; [mArray removeObjectAtIndex:1]; // A, C, D [mArray removeObjectAtIndex:1]; // A, D [mArray removeAllObjects]; // [Empty] 37 NSMutableArray ▽ ソート ‣ - (void)sortUsingSelector:(SEL)comparator • 配列内のオブジェクトをcomparatorで昇順にソート • NSArrayのsortedArrayUsingSelector:とは異な り、Receiverの配列自体が更新される NSMutableArray *mArray = [NSMutableArray arrayWithObjects:@"B", @"A", @"C", nil]; [mArray sortUsingSelector:@selector(compare:)]; // A, B, C 38 辞書 辞書とは?(1/3) • キーとそれに対応する値のペア(エントリー)を格 納するコレクション ➡ キーも値もオブジェクト (nilは不可) • キーを用いて値を指定 39 辞書 辞書とは?(2/3) • キーに関する注意点 • NSCopyingプロトコルへの準拠が必須 ➡ 文字列(NSString)を利用するのが一般的 • 辞書内に同一のキーは存在できない ➡ 同一性はNSObjectのisEqual:メソッドで判定 40 辞書 辞書とは?(3/3) ‣ NSDictionary • 不変な辞書を扱うクラス ‣ NSMutableDictionary • • 可変な辞書を扱うクラス NSDictionaryのサブクラス 41 NSDictionary 主なメソッドと使用例 ▽ インスタンスの作成と初期化 ‣ - (id)initWithObjectsAndKeys:(id)firstObject , ... ‣ + (id)dictionaryWithObjectsAndKeys:(id)firstObject , ... • 引数で指定した可変個のエントリー(値、キーの順で 指定)を格納した辞書を作成して返す • 引数はコンマで区切り、最後に必ずnilを指定 NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil]; 42 NSDictionary ▽ サイズ ‣ - (NSUInteger)count • 辞書内のエントリーの個数を返す NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil]; NSUInteger count = [dictionary count]; // 2 43 NSDictionary ▽ オブジェクトの取得 ‣ - (id)objectForKey:(id)aKey • aKeyで指定したキーに対応する値を返す • 対応する値がない場合にはnil NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil]; id object = [dictionary objectForKey:@"key1"]; // value1 object = [dictionary objectForKey:@"key3"]; // nil 44 NSMutableDictionary 主なメソッドと使用例 ▽ インスタンスの作成と初期化(1/2) ‣ - (id)init; ‣ + (id)dictionary; • 空の辞書を作成して返す NSMutableDictionary *mDict = [NSMutableDictionary dictionary]; 45 NSMutableDictionary 主なメソッドと使用例 ▽ インスタンスの作成と初期化(2/2) ‣ - (id)initWithCapacity:(NSUInteger)numItems ‣ + (id)dictionaryWithCapacity:(NSUInteger)numItems • numItemsで指定した個数のエントリーを格納するのに 十分なメモリを割り当てた辞書を作成して返す ➡ 後からこのサイズを超えても問題ない NSMutableDictionary *mDict = [NSMutableDictionary dictionaryWithCapacity:3]; 46 NSMutableDictionary ▽ エントリーの追加 ‣ - (void)setObject:(id)anObject forKey:(id)aKey • 辞書にanObject, aKeyで指定したエントリーを追加 • nilの指定は不可 • 辞書内に既に存在するaKeyを指定した場合には、 対応する値を削除し、anObjectを追加 NSMutableDictionary *mDict = [NSMutableDictionary dictionary]; [mDict setObject:@"value1" forKey:@"key"]; [mDict setObject:@"value2" forKey:@"key"]; // value1はvalue2に置換 47 NSMutableDictionary ▽ エントリーの削除 ‣ - (void)removeObjectForKey:(id)aKey • aKeyで指定したキーに対応するエントリーを削除 • 対応するエントリーがない場合には何もしない NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil]; [dictionary removeObjectForKey:@"key1"]; [dictionary removeObjectForKey:@"key3"]; // 何もしない 48 その他 コレクションに関連する仕組みとクラス • for in 構文 • NSNull • ラッパークラス 49 for in 構文 for in 構文とは? • コレクション内のオブジェクトを高速に列挙 ➡ 列挙:1つづつ取り出す • NSFastEnumerationプロトコルに準拠した クラスで使用可能 ‣ NSArray • 配列内のオブジェクトを先頭から順に列挙 ‣ NSDictionary • 辞書に格納されたキーを列挙(順序は不定) 50 for in 構文 書式 // オブジェクト型の変数を内部で宣言する場合 for(オブジェクト型 変数 in コレクション) { // 変数を使用する文... } // オブジェクト型の変数を外部で宣言する場合 オブジェクト型 変数; for(変数 in コレクション) { // 変数を使用する文... } 51 for in 構文 使用例 // NSArray NSArray *array = [NSArray arrayWithObjects:@"A", @"B", @"C", nil]; for(NSString *string in array) { NSLog(@"%@", string); } // NSDictionary NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil]; NSString *key; for(key in dictionary) { NSString *value = [dictionary objectForKey:key]; NSLog(@"%@", value); } 52 NSNull NSNullとは? • 何もない(Null)ことを表すクラス • コレクションに格納できないnilの代わりに使用 ‣ + (id)null • NSNullのインスタンスを返す • 常に同じインスタンスが返される ➡ NSNullかどうかをポインタ比較で判定可能 ➡ alloc, initでの作成は不可 53 NSNull 使用例 NSArray *array = [NSArray arrayWithObjects:@"A", @"B", [NSNull null], @"D", [NSNull null], nil]; for(id object in array) { // 列挙されたオブジェクトがNSNullでなかったら出力 if(object != [NSNull null]) { NSLog(@"%@", object); } } 54 ラッパークラス ラッパー(Wrapper)クラスとは? • オブジェクトではないデータ型をオブジェクト して扱えるようにするためのクラス ➡ コレクション内に格納可能 • 主なラッパークラス • NSNumber • NSValue ※講義では扱わない 55 ラッパークラス NSNumber • 数値とそれに準ずるデータ型のためのラッパー クラス • 取り扱えるデータ型 BOOL, char, double, float, int, long, long long, short, unsigned char, unsigned int, unsigned long, unsigned long long, unsigned short, NSInteger, NSUInteger 56 ラッパークラス NSNumberのメソッド(int型の場合) ‣ - (id)initWithInt:(int)value ‣ + (NSNumber *)numberWithInt:(int)value • ‣ int型のvalueを指定してインスタンスを作成して返す - (int)intValue • インスタンスに格納された値をint型の値として返す ➡ 取り扱えるデータ型のすべてに上記に相当するメソッド がある 57 ラッパークラス 使用例 // 数値を辞書に格納して取得・出力 NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; [dictionary setObject:[NSNumber numberWithInt:2] forKey:@"Key1"]; [dictionary setObject:[NSNumber numberWithInt:10] forKey:@"Key2"]; for(NSString *key in dictionary) { NSNumber *number = [dictionary objectForKey:key]; int rawNumber = [number intValue]; NSLog(@"%d", rawNumber); } 58 【参考】 通知 通知 通知とは? • オブジェクトから他のオブジェクトへイベント の発生を知らせること • ex. データの更新完了、画面の回転 など 直接通知方式 • 必要なオブジェクト間で直接通知を行う ➡最も単純な通知方式 60 通知 直接通知方式の問題点 • 通知の送信側と受信側のオブジェクトを直接関 連付ける必要性 ➡ オブジェクト間の独立性の低下 ➡ プログラムの再利用性の低下 ➡ プログラムの変更コストの増加 61 通知 通知センター方式(1/2) • Foundationで採用されている通知方式 • 通知センターという第3者を介在させて通知 ➡オブジェクト間の独立性を維持しつつ 通知を実施 62 通知 通知センター方式(2/2) 送信者 • 通知センターに通知を送信(ポスト) 監視者 • • 通知センターから通知を受信 予め監視者として通知センターに登録 通知センター • 通知を送信者から受信したら、その通 知の監視者に通知を送信 63 通知 NSNotification(1/2) • 通知を表すクラス ‣ + (id)notificationWithName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)userInfo • 通知を表すインスタンスを作成して返す • aNameに通知名、anObjectに通知の送信者、userInfo に通知の際に同時に送りたい情報を指定 • anObject、userInfoはnilでも可 NSNotification *notification = [NSNotification notificationWithName:@"NotificationName" object:self useInfo:nil]; 64 通知 NSNotification(2/2) ‣ - (NSString *)name ‣ - (id)object ‣ - (NSDictionary *)userInfo • 通知に格納されている通知名、送信者、userInfoをそ れぞれ返す 65 通知 NSNotificationCenter • 通知センターのクラス ▽ 通知センターの取得 ‣ + (id)defaultCenter • 通知センターのインスタンスを返す ➡ alloc, initなどは使用しない ➡ 所有は発生しない NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 66 通知 ▽ 監視者の登録(1/3) ‣ - (void)addObserver:(id)notificationObserver selector:(SEL)notificationSelector name:(NSString *)notificationName object:(id)notificationSender • 監視に関する詳細を通知センターに登録(複数登録可) • notificationObserver:監視者のオブジェクト • notificationSelector:監視者が通知を受信した際に呼 ばれるメソッドのセレクター。メソッドは通知を表す NSNotificationのオブジェクトを引数に持つ。 ex. - (void)notificationHandler:(NSNotification *)notification; 67 通知 ▽ 監視者の登録(2/3) • notificationName:監視者が監視する通知名。nilを指 定可能(指定なしとみなされる)。 • notificationSender:監視者が監視する通知の送信者。 nilを指定可能(指定なしとみなされる)。 通知名 送信者 監視者に通知される対象 指定あり 指定あり 特定の通知名、特定の送信者からの通知 指定あり 指定なし 特定の通知名を持つ全ての通知 指定なし 指定あり 特定の送信者からの全ての通知 指定なし 指定なし 全ての通知 68 通知 ▽ 監視者の登録(3/3) /* objectが -(void)notificationHandler:(NSNotification *)notification メソッドを持つと仮定 */ // 任意の送信者からの NotificationName という通知名の通知を // 受信する監視者objectを通知センターに登録 NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:object selector:@selector(notificationHandler:) name:@"NotificationName" object:nil]; 69 通知 ▽ 監視者の削除 ‣ - (void)removeObserver:(id)notificationObserver name: (NSString *)notificationName object:(id)notificationSender ‣ - (void)removeObserver:(id)notificationObserver • 通知センターに登録した監視者を削除 • 後者は全ての登録を削除 ※重要 • 通知センターは監視者として登録したオブジェクトを 所有しないので、監視者がメモリから解放される前に 必ず通知センターから監視者を削除すること! NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center removeObserver:self]; 70 通知 ▽ 通知のポスト ‣ - (void)postNotification:(NSNotification *)notification ‣ - (void)postNotificationName:(NSString *)notificationName object:(id)notificationSender userInfo:(NSDictionary *)userInfo • 通知センターに通知をポスト • 前者は通知オブジェクトを指定 • 後者は通知の各種情報を指定 [[NSNotificationCenter defaultCenter] postNotificationName:@"NotificationName" object:self userInfo:nil]; 71
© Copyright 2025 ExpyDoc