Objective-C初心者のためのNSArray基礎5選 – Japanシーモア

Objective-C初心者のためのNSArray基礎5選

プログラミング初心者がObjective-CのNSArrayを学ぶためのイメージObjctive-C
この記事は約20分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

このサービスは複数のSSPによる協力の下、運営されています。

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

プログラミングでは、データの集合を効率的に扱うためのさまざまなデータ構造が使用されます。

Objective-Cにおいても、NSArrayはデータの集まりを管理する基本的なデータ構造の一つであり、その使い方をマスターすることは、開発の基礎を学ぶ上で非常に重要です。

この記事では、NSArrayの基本から応用、注意すべき点、カスタマイズ方法までを、5つの具体的な例を通じて解説します。

Objective-Cをこれから学びたい初心者の方々にとって、ここでの学びがプログラミングスキルの向上につながることを願っています。

●Objective-Cとは

Objective-Cは、AppleのiOSやmacOSのアプリケーション開発で長年にわたり使用されてきたプログラミング言語です。

C言語をベースにSmalltalkのオブジェクト指向機能が追加されており、C言語のすべての機能に加えて、クラス、継承、ポリモーフィズム、エンカプスレーションなどのオブジェクト指向プログラミングの概念をサポートしています。

○Objective-Cの概要

Objective-Cは、厳格な型付け、オブジェクト指向、動的メッセージングなどの特徴を持つ言語です。

これにより、開発者は柔軟で強力なコードを書くことができ、大規模なアプリケーション開発においてもその力を発揮します。

また、Objective-CはAppleのCocoaとCocoa Touchフレームワークの主要な言語として採用されているため、Appleのエコシステムでアプリを開発する上で中心的な役割を果たします。

○Objective-Cでできること

Objective-Cを学ぶことで、あらゆるApple製品向けのアプリケーション開発が可能になります。

これにはiOSデバイスのためのモバイルアプリやmacOS用のデスクトップアプリ、さらにはApple WatchやApple TVといったプラットフォームのアプリケーションも含まれます。

Objective-Cによる開発は、強力なフレームワークとライブラリのサポートを受けるため、機能的でセキュアなアプリを比較的容易に作成することができます。

●NSArrayとは

NSArrayはObjective-Cにおける配列を操作するためのクラスです。

Objective-Cを利用してアプリケーションを開発する際に、複数のデータを格納する基本的なデータ構造として活用されます。

NSArrayはイミュータブル(不変)であり、一度作成するとその内容を変更することはできません。

内容を変更するには、NSMutableArrayという別のクラスを用いる必要があります。

Objective-CのNSArrayは、順序付けられたコレクションとして、要素を一連のインデックスと共に格納します。

各要素はNSObjectクラスの任意のオブジェクトを指すことができ、そのために様々なタイプのデータを同じ配列内に保持することが可能です。

しかし、異なるデータ型を含む場合には、各要素の型を意識して操作する必要があります。

Objective-Cでは、NSArrayの初期化にいくつかの方法が提供されており、静的な配列リテラルやクラスメソッドを使用してインスタンスを生成することができます。

初期化の際には、配列に含めるオブジェクトを指定するか、または既存のNSArrayオブジェクトからコピーを作成することで新たなNSArrayインスタンスを得ることができます。

○NSArrayの基本

NSArrayの基本的な使用法は、複数のオブジェクトを順番に管理することです。

これにより、要素の集合に順番をつけて簡単にアクセスすることができます。

例えば、アプリケーションでユーザーのリストや商品のリストを表示する場合など、順序が重要な情報を扱う際に非常に便利です。

NSMutableArrayとの違いを理解することも重要です。NSMutableArrayはNSArrayのサブクラスであり、要素の追加や削除が可能です。

これは動的なデータコレクションを扱う際に適しており、アプリケーションの状況に応じて配列の内容を変更したい場合に使用します。

しかし、配列の内容が頻繁に変更されない場合、または配列の内容を変更する権限を制限したい場合にはNSArrayを使用すると良いでしょう。

さらに、NSArrayはシリアライズやディシリアライズが容易であり、ファイルやネットワークを介してデータを簡単に送受信できるため、データの永続化やリモートデータの処理においても広く利用されています。

また、for-inループやブロック構文を使用して、簡単に要素を列挙したり、特定の条件に合致する要素を探し出したりすることが可能です。

○NSArrayとNSMutableArrayの違い

NSArrayとNSMutableArrayの違いはその変更可能性にあります。

NSArrayはそのサイズや内容を変更することができない静的な配列を提供します。

一方で、NSMutableArrayは要素の追加、削除、置換などが可能であり、動的な配列操作に適しています。

例えば、一定のデータセットに基づく一覧を表示する場合にはNSArrayを使うと良いでしょう。

一方、ユーザーによるデータの追加や削除を反映するリストを管理する場合は、NSMutableArrayが適しています。

●NSArrayの使い方

Objective-CにおけるNSArrayの使い方は多岐にわたりますが、基本から学ぶことが重要です。

NSArrayは不変の配列で、そのサイズや内容を後から変更することはできません。

配列を作成した後は、配列内のオブジェクトへの読み取りアクセスのみが可能です。

これはプログラムの予測可能性と安全性を高めるのに役立ちます。

では、このNSArrayの使い方をいくつかの主要な操作を通して見ていきましょう。

○配列の初期化と要素の追加

NSArrayを初期化する最も一般的な方法はリテラル構文を使用することです。

これにより、コードの可読性が高く、簡単に複数の要素を含む配列を作成できます。

// 配列を初期化するコード例
NSArray *fruits = @[@"Apple", @"Orange", @"Banana"];

このコードでは@[]を使ってfruitsという名前のNSArrayを初期化しており、@"Apple", @"Orange", @"Banana"の3つの文字列が要素として含まれています。

この例では、静的な配列を作成し、そこに3つの果物の名前を追加しています。

○NSArrayでのループ処理

NSArrayに含まれる各要素に対して操作を行いたい場合、for-inループを使用すると便利です。

これは配列の各要素に対して繰り返し処理を行う標準的な方法です。

// NSArrayをループ処理するコード例
for (NSString *fruit in fruits) {
    NSLog(@"%@", fruit);
}

上記のコードでは、fruits配列の各要素をfruitという変数に代入し、その都度NSLogを使用してコンソールに出力しています。

このループにより、配列内の全ての果物の名前が出力されます。

○NSArrayの要素へのアクセス方法

NSArrayの要素にアクセスするには、主にobjectAtIndex:メソッドを使用します。

このメソッドを使うことで、配列内の指定した位置にあるオブジェクトを取得することができます。

// 配列の特定の要素にアクセスするコード例
NSString *firstFruit = [fruits objectAtIndex:0]; // Appleを取得
NSString *secondFruit = fruits[1]; // インデックス構文を使ってOrangeを取得
NSLog(@"First: %@, Second: %@", firstFruit, secondFruit);

上記のサンプルでは、objectAtIndex:メソッドと新しいインデックス構文fruits[1]を使用しています。

これにより、最初と2番目の要素に簡単にアクセスし、その結果を出力しています。

出力結果は、最初に”Apple”が、次に”Orange”がコンソールに表示されるでしょう。

○NSArrayのサンプルコード1:特定の要素を検索する

Objective-CでNSArrayを使用する際、特定の要素を検索することは非常に一般的な操作です。

配列の中にあるオブジェクトを探し出すためには、indexOfObject: メソッドを使うことができます。

このメソッドは、引数として渡されたオブジェクトが配列のどの位置にあるかを返します。

オブジェクトが配列内に存在しない場合は、NSNotFound を返します。

下記のサンプルコードでは、文字列の配列から特定の文字列を検索し、そのインデックスを見つける方法を表しています。

// 文字列の配列を作成
NSArray *fruits = @[@"apple", @"orange", @"banana", @"mango", @"lemon"];

// "banana"のインデックスを検索
NSUInteger bananaIndex = [fruits indexOfObject:@"banana"];

// 結果をログに出力
if (bananaIndex != NSNotFound) {
    NSLog(@"'banana'は配列の%lu番目にあります。", (unsigned long)bananaIndex);
} else {
    NSLog(@"'banana'は配列に存在しません。");
}

このコードではまず、5つの果物の名前を含むNSArrayを作成しています。

次にindexOfObject:を使って”banana”の位置を調べ、見つかった場合はそのインデックスを、見つからなければNSNotFoundを受け取ります。

ログ出力を行う部分で、条件分岐を使い、”banana”が見つかった場合にはその位置を、見つからなかった場合には存在しないことをユーザーに通知します。

このコードを実行すると、”banana”が配列の何番目にあるかがコンソールに出力されます。

仮に”banana”が配列に含まれていなければ、’banana’は配列に存在しません。というメッセージが表示されるでしょう。

○NSArrayのサンプルコード2:配列をソートする

NSArrayの要素を順序付けるには、さまざまな方法がありますが、最も一般的なのはsortedArrayUsingSelector:メソッドを使用することです。

このメソッドは、比較セレクタを指定して、そのセレクタに基づいて配列をソートします。

たとえば、文字列の配列をアルファベット順に並び替えることができます。

次に、文字列の配列をソートするサンプルコードを紹介します。

// 文字列の配列を作成
NSArray *fruits = @[@"apple", @"orange", @"banana", @"mango", @"lemon"];

// セレクタcompare:を用いて配列をソート
NSArray *sortedFruits = [fruits sortedArrayUsingSelector:@selector(compare:)];

// ソートされた配列をログに出力
NSLog(@"ソートされた配列: %@", sortedFruits);

このコードでは、最初にNSArrayオブジェクトfruitsを作成し、sortedArrayUsingSelector:メソッドを呼び出しています。

引数に@selector(compare:)を渡すことで、NSStringが提供する標準の比較メソッドを使って配列の要素をソートします。

結果として得られるソート済み配列をログに出力することで、操作の成果を確認できます。

このコードを実行すると、配列の要素がアルファベット順に並べ替えられた状態でコンソールに出力されます。

こうして配列のソートを行うことで、データを整理したり、ユーザーにとって見やすい形式で情報を提示したりすることが容易になります。

●Objective-CにおけるNSArrayの応用例

NSArrayはObjective-Cにおいて不可欠なデータ構造の一つであり、その応用範囲は非常に広いです。

配列を扱う上での応用例を3つ紹介します。

各応用例には具体的なコードとその実行結果の説明を加えていきます。

○NSArrayのサンプルコード3:複数の配列を結合する

配列の結合は、異なるデータセットをまとめたい場合などに便利です。

Objective-CではarrayByAddingObjectsFromArray:メソッドを用いて簡単に複数の配列を結合することができます。

// 配列を二つ用意します
NSArray *firstArray = @[@"Apple", @"Banana"];
NSArray *secondArray = @[@"Orange", @"Peach"];

// firstArrayにsecondArrayを結合します
NSArray *combinedArray = [firstArray arrayByAddingObjectsFromArray:secondArray];

このコードではまず、文字列オブジェクトを要素とする二つの配列firstArraysecondArrayを用意しています。

arrayByAddingObjectsFromArray:メソッドを用いてこれらの配列を結合し、新たな配列combinedArrayを生成しています。

この処理を行うと、combinedArrayには@"Apple", @"Banana", @"Orange", @"Peach"という要素が順に格納されます。

○NSArrayのサンプルコード4:配列からランダムに要素を取得する

配列の要素からランダムにアイテムを取得するには、arc4random_uniform関数を使用することが一般的です。

// 要素がいくつかの文字列を含む配列を用意します
NSArray *fruits = @[@"Apple", @"Banana", @"Cherry", @"Date", @"Elderberry"];

// arc4random_uniformを使ってランダムなインデックスを生成します
NSUInteger randomIndex = arc4random_uniform((uint32_t)[fruits count]);

// 配列からランダムな要素を取得します
NSString *randomFruit = fruits[randomIndex];

このコードでは、最初に5つの果物の名前を要素に持つ配列fruitsを用意しています。

その後、arc4random_uniform関数を使って0から配列の要素数未満のランダムな整数randomIndexを生成し、そのインデックスに対応する配列の要素を取得しています。

この処理を実行すると、randomFruitにはfruits配列からランダムに選ばれた1つの文字列が格納されます。

○NSArrayのサンプルコード5:配列をファイルに保存する

Objective-Cでは配列をファイルに保存することが可能で、これはアプリケーションの設定や状態を永続化するのに役立ちます。

writeToFile:atomically:メソッドを使って配列をファイルに保存することができます。

// 保存するための配列を作成します
NSArray *colors = @[@"Red", @"Green", @"Blue"];

// ドキュメントディレクトリのパスを取得します
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"colors.plist"];

// 配列をファイルに書き込みます
[colors writeToFile:filePath atomically:YES];

このコードでは、まずcolorsという配列を作成し、その後にファイルシステム上のドキュメントディレクトリのパスを取得しています。

そしてwriteToFile:atomically:メソッドを使用して、この配列をcolors.plistという名前のファイルに保存しています。

この処理を行うと、colors配列の内容がドキュメントディレクトリ内のcolors.plistファイルに書き込まれ、アプリケーションの再起動後も情報を保持することができます。

●注意点と対処法

Objective-Cを学ぶ過程でNSArrayを使用する際にはいくつかの注意点があります。

これらの注意点をしっかり理解し、それぞれに対応する対処法を知ることで、効率的なプログラミングが可能になります。

ここでは、よく遭遇する問題とその解決策を紹介します。

○インデックスの範囲外エラー

NSArrayのインデックスエラーは、配列の範囲外の要素にアクセスしようとした時に発生します。

例えば、5つの要素を持つ配列に対して、6番目の要素を取得しようとするとエラーが発生します。

この問題を避けるためには、常に配列のcountプロパティをチェックして、要求されたインデックスが配列のサイズ内にあることを確認する必要があります。

下記のコードスニペットは、安全に配列要素にアクセスする方法を表しています。

NSArray *fruits = @[@"Apple", @"Banana", @"Cherry", @"Date", @"Elderberry"];
NSUInteger index = 5; // このインデックスは配列のサイズを超えています。

if(index < fruits.count){
    NSString *fruit = fruits[index];
    NSLog(@"Selected fruit: %@", fruit);
} else {
    NSLog(@"Index is out of bounds.");
}

このコードでは、配列fruitsの要素数をcountプロパティで取得し、インデックスがこの範囲内かどうかをif文でチェックしています。

インデックスが範囲内であれば要素を取得し、範囲外であればエラーメッセージを表示します。

このようにプログラムすることで、実行時のエラーを防ぐことができます。

このコードを実行すると、「Index is out of bounds.」というログが出力されます。

これは、指定したインデックスが配列の要素数を超えているためです。

○変更不可なNSArrayの変更

NSArrayは変更不可能な配列であり、一度作成するとその内容を変更することはできません。

要素を追加、削除、または変更したい場合は、NSMutableArrayを使用する必要があります。

しかし、NSArrayに対して変更を試みた場合、プログラムはクラッシュする可能性があります。

対処法として、NSArrayをNSMutableArrayに変換してから変更を行うことが挙げられます。

下記の例では、NSArrayからNSMutableArrayを作成し、新たな要素を配列に追加しています。

NSArray *immutableArray = @[@"Tokyo", @"Osaka", @"Kyoto"];
NSMutableArray *mutableArray = [immutableArray mutableCopy]; // NSArrayをNSMutableArrayに変換

[mutableArray addObject:@"Hokkaido"]; // 新しい要素を追加
NSLog(@"Updated array: %@", mutableArray);

このコードでは、immutableArrayの内容を変更可能なmutableArrayにコピーしています。

その後、addObject:メソッドを使ってmutableArrayに「Hokkaido」を追加しています。

ログを出力すると、変更後の配列が表示されます。

●NSArrayのカスタマイズ方法

Objective-Cでは、NSArrayは不変の配列を表すクラスで、一度作成するとその内容を変更することができません。

しかし、プログラムが成長し、要件が変化するにつれ、既存のNSArrayクラスに新しい機能を加えたいと考える開発者も多いでしょう。

NSArrayをカスタマイズする方法として、カテゴリを追加する方法やブロックを使用したカスタマイズ方法があります。

これらのテクニックを使えば、NSArrayの機能を拡張し、アプリケーションのニーズに合わせて利便性を高めることが可能です。

○カテゴリを使用したNSArrayの拡張

Objective-Cではカテゴリという機能を使用して既存のクラスに新しいメソッドを追加することができます。

これにより、オリジナルのクラス定義を変更することなく、必要に応じて機能を拡張することが可能になります。

例えば、配列内の全要素に対してある操作を実行するメソッドや、条件に一致する要素だけを抽出するフィルタリングメソッドなど、便利な操作を追加することができます。

カテゴリを定義する際には、対象となるクラス名の後ろにカテゴリ名をカッコで囲んで宣言します。

ここでは、NSArrayにカスタムメソッドを追加するカテゴリの定義方法と、使用方法を表すサンプルコードを紹介します。

// NSArray+CustomMethods.h
@interface NSArray (CustomMethods)
- (NSArray *)filteredArrayUsingBlock:(BOOL (^)(id obj, NSUInteger idx))block;
@end

// NSArray+CustomMethods.m
@implementation NSArray (CustomMethods)
- (NSArray *)filteredArrayUsingBlock:(BOOL (^)(id obj, NSUInteger idx))block {
    NSMutableArray *filteredArray = [NSMutableArray array];
    [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if (block(obj, idx)) {
            [filteredArray addObject:obj];
        }
    }];
    return filteredArray.copy;
}
@end

このコードでは「filteredArrayUsingBlock:」というメソッドをNSArrayクラスのカテゴリとして追加しています。

このメソッドは、配列の各要素に対してユーザーが指定したブロックを実行し、ブロックがYESを返す要素だけを含む新しい配列を作成して返します。

○ブロックを使用した配列のカスタマイズ

Objective-Cのブロックは、C言語の関数ポインタに似ているが、それに加えてスコープ内の変数をキャプチャして使用することができる機能です。

NSArrayの各要素に対するカスタム操作を行う際にもブロックを利用すると、柔軟かつ強力なカスタマイズが実現できます。

たとえば、特定の条件に一致する要素の数を数えたり、特定の処理を適用して新しい配列を作成することが可能です。

ここでは、NSArrayの要素に対してブロックを使ったカスタマイズの例を紹介します。

// 配列内の数値が5より大きい要素のみを抽出する例
NSArray *originalArray = @[@1, @2, @5, @7, @8, @10];
NSArray *filteredArray = [originalArray filteredArrayUsingBlock:^BOOL(id obj, NSUInteger idx) {
    return [obj integerValue] > 5;
}];

NSLog(@"Filtered Array: %@", filteredArray);

このサンプルコードでは、最初に定義したカスタムメソッド「filteredArrayUsingBlock:」を使用して、originalArrayから数値が5より大きい要素だけを抽出しています。

実行すると、結果として「Filtered Array: (7, 8, 10)」という出力が得られます。

まとめ

この記事では、Objective-CにおけるNSArrayの操作について、この記事では基本的な使い方から始めて、NSMutableArrayとの違い、ループ処理、要素へのアクセス方法、さらには配列の検索、ソート、結合、ランダムアクセス、ファイル保存のサンプルコードに至るまで詳細に解説しました。

Objective-Cを学び始めた初心者にとってNSArrayは、データを扱う上で避けて通れない基礎知識であり、この記事がその理解を深める一助となれば幸いです。