*

Xcode&Objective-Cの文字列処理をユニットテスト(XCTestフレームワーク)で確認する。[NSStringの比較]

公開日: : 最終更新日:2014/06/30 Objective-C , ,


スポンサードリンク



前回は、NSStringの定義、分割、検索の各処理を確認しました。
二回目は、NSStringの比較の処理を確認します。

今回も、前回と同様にユニットテスト形式で実際の確認を行うコードを記載いたします。

利用しているXcodeはXcode5(5.1)となります。

ユニットテストに関しては
「Xcode5でUnitTestを利用してみる。」をまずはご覧いただければ幸いです。

第二回は

を説明させていただきます。

NSStringの比較メソッド

NSStringの比較系メソッドは多く存在しています。
その背景には、こんな時はこのメソッドを使うのがコードの文字数が少なくて良い。
こんな時には、細かい条件を指定してこのメソッドを使うの良い。
等の考えがあるからだと思います。

と言う事で、今回はNSStringの4つの比較メソッドを、ユニットテストを書きながら確認していきます。

isEqualToStringメソッド

もっともシンプルな比較メソッドです。

ここで、注意事項なのですが、Javaでも、文字列の比較は==演算子で行うと、
うまくいったり、いかなかったりしますよね、結局は、オブジェクトの格納アドレスに依存する処理となりますので、
Objective-Cでも==演算子では比較しないでください。

まずは日本語の比較からいってみます。

“ガンダム”は”マクロス”ではありません。

テストは予想通り成功しました。

次は、なぜisEqualToStringがもっともシンプルな比較メソッドかが分かるアサーションを追加してみました。

isEqualToStringのシンプルさが分かる例

コメントにも記載していますが、isEqualToStringは大文字小文字を区別する比較しかできません。
オーバーロードされたメソッドも存在しませんので、もっともシンプルな文字列比較メソッドであると言えます。

1つ注意しなければいけないポイントが、この「大文字小文字を区別する比較」にあります。

前回のrangeOfStringメソッド
のoptions引数に指定できるNSStringCompareOptionsのNSLiteralSearch
が「大文字小文字を区別する比較」の設定値となっており、このNSLiteralSearchには「大文字小文字を区別する比較」以外の意味を持っています。

先ほどのコード例で出てきた”ガンダム”ですが、濁点を1文字として分けて入力した”ガンダム”と一緒に入力した”ガンダム”
がNSLiteralSearchの検索では同じ文字列として認識されません。
(正確には、UTF-8-MACは濁点を1文字で扱い、それ以外のUTF-8は2文字で扱う)

当然ですが、NSLiteralSearchの動きのisEqualToString:メソッドも同じ動作となります。

isEqualToStringで注意すべきポイント

テストケース内の各NSStringの変数
stringValue1が濁点を一括して入力した文字列(文字コード指定)
stringValue2が濁点を分割して入力した文字列(文字コード指定)
stringValue1が濁点を一括して入力した文字列(文字列指定)
です。

まずは、
isEqualToStringでstringValue1とstringValue2を比較するとTRUE
isEqualToStringでstringValue1とstringValue3を比較するとTRUE
となるアサーションを記述してみます。

stringValue1とstringValue2は一致しないのでテストは失敗するはずです。

実行結果は以下の通りです。やはり11行目は失敗しました。
スクリーンショット 2014-05-22 14.59.26

11行目をXCTAssertFalseに変更して、再度テストを実行すると成功しました。

以上が、NSLiteralSearchのisEqualToStringの注意すべきポイントです。

実行しようとしている処理が、isEqualToStringで充足できるのかを考えた上で利用してください。
isEqualToStringは他の文字列比較に比べると速度的なメリットはあるはずです。

caseInsensitiveCompareメソッド

isEqualToStringの比較方法をNSCaseInsensitiveSearchに変えただけのメソッドです。
NSCaseInsensitiveSearchは「大文字小文字を区別しない比較」を行うとのNSStringCompareOptionsの値です。

caseInsensitiveCompareの戻り値はNSComparisonResultです。

NSComparisonResultに含まれる定義は以下の通りです。

  •  NSOrderedAscending:「レシーバ < 引数のNSString」
  •  NSOrderedSame:「レシーバが引数のNSStringと一致」
  •  NSOrderedDescending:「レシーバ > 引数のNSString」

「大文字小文字を区別しない比較」以外にも、isEqualToStringの所で説明した濁点の使い方の違いも吸収して
同じ文字列として判定してくれます。
caseInsensitiveCompareにもオーバーロードされたメソッドは存在しませんので、この動きだけしか期待できません。
まあ、その分シンプルにNSCaseInsensitiveSearchな文字列比較を実装できます。

isEqualToStringで書い比較内容と同じアサーションをいっきに確認してみます。

予想通りです。全てのアサーションが成功しました。

繰り返しになりますが、caseInsensitiveCompareを利用することで、NSCaseInsensitiveSearchな文字列比較を実装できます。

compareメソッド

compareメソッドには以下の4つが存在しますが、戻り値は全てNSComparisonResultです。

  • compare:
  • compare:options:
  • compare:options:range:
  • compare:options:range:locale

見ていただいて分かる通り、前回説明させていただいたrangeOfStringとは同じバリエーションです。

当然、各引数の指定方法も同じですが戻り値は異なります。
まあ、文字列比較(compare)と、文字列検索(rangeOfString)メソッドですからこの違いにはうなずけます。

rangeOfStringメソッドではrange指定の検索処理を試していませんでしたので、
compareメソッドではcompare指定を試してみようと思います.

まずは、compare:メソッドのアサーションを書いてみます。
他の同じようなメソッドと同じ仕様で、optionsが指定できるオーバーロードメソッドがある場合のデフォルトはNSLiteralSearchとなります。

次は、compare:options:を試してみます。
もう動作が予想できているのであまり意味無いですが・・・

最後に、compare:options:range:を試してみます。
rangeに指定するNSRangeですが、以下のようにして生成可能です。

rangeの説明も終わりましたので
“AbcDEF”と”abcdef”、”AbcdEF”を先頭から3文字、NSLiteralSearchで比較してみます。

 

うんうん、うん・・・、テストは失敗しました。
えーーーー、なんでやねん!
スクリーンショット 2014-05-23 14.54.40

理由は、rangeはレシーバに対してのみ効果を発揮する引数だからです。

先ほどのコードのcompareの第一引数の長さを3文字に変更してみました。

テストも成功しました。
スクリーンショット 2014-05-23 15.06.26

hasPrefixメソッドとhasSuffixメソッド

hasPrefixメソッド

レシーバが任意の文字列から開始されているかを確認するメソッドです。
オーバーロードされたメソッドは存在しておりませんので、
NSLiteralSearch(大文字小文字を区別して比較)の動きとなります。この仕様は一貫していますので分かりやすいですね。

NSCaseInsensitiveSearch(大文字小文字関係なく比較)での比較を行いたい場合は、compare:options:range:メソッドを利用してください。

利用例は以下の通りです。

hasSuffixメソッド

レシーバが任意の文字列で終了しているかを確認するメソッドです。
hasPrefixと同様に、オーバーロードされたメソッドは存在しておりませんので、
NSLiteralSearch(大文字小文字を区別して比較)の動きとなります。

利用例は以下の通りです。


スポンサードリンク

Googleアドセンス

Googleアドセンス




関連記事

Xcode&Objective-Cのまとめエントリー

エントリーもまずまず揃ってきたので、まとめのエントリーを作成しておこうと思います。 基本的には、各

記事を読む

Objective-Cでコールバック処理を@Selectorで実現する方法

最近はSwiftばっかり読み書きしていますが、既存のライブラリをカスタマイズして使うことも多いので

記事を読む

Xcode&Objective-Cの文字列処理をユニットテスト(XCTestフレームワーク)で確認する。[NSStringを数値に変換する方法]

「Xcode&Objective-Cの文字列処理をユニットテスト(XCTestフレームワーク)で確認

記事を読む

Xcode5で画面にナビゲーションバーを配置して利用する。

今回は「ナビゲーションバー」をiPhoneアプリの画面に配置して利用する方法を記載させていただきます

記事を読む

Xcodeの使い方[ツールバー]

Xcode5(iOS7対応バージョンの統合開発)の「ツールバー」の使い方のエントリーとなります。

記事を読む

Xcodeの使い方[エディタエリアのテキストエディタ]

「Xcodeの使い方」に引き続き「 Xcode5のエディタエリアの使い方[テキストエディタの使い方]

記事を読む

Xcodeのユーティリティエリアの使い方[ソースファイル表示時]

本エントリーでは、Xcodeの「ユーティリティエリア」の使い方を説明させていただきます。 利用

記事を読む

Xcode5&Objective-Cでセグエを利用して画面遷移を実現する。[前編:モックの作成]

iPhoneアプリの画面遷移と言えば、真っ先に挙がるのが「ナビゲーションコントローラ」なのですが

記事を読む

Xcode(Objective-C)のデリゲートとプロトコルの使い方[前編]

Xcode(Xcode5でも同様)でアプリ開発をしていて、少し複雑な事をしようとするとデリゲートと言

記事を読む

Xcodeのユーティリティエリアの使い方[ストーリーボード表示時の「Attributes」,「Size」,「Connections」Inspector]

本エントリーでは、「Xcodeのユーティリティエリアの使い方」に引き続き、「ストーリーボード」表示時

記事を読む

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

動画で英語を学習できるiOSの無料アプリCapTubeをリリースいたしました。

個人では初となるiOSアプリをリリースいたしました。 何度もリジ

no image
Ruby on rails4系でBootstrapを利用するためのtips

MacでRuby on rails4系のBootstrapを利用しよう

no image
Java、Eclipse、JUnit関連のエントリーの移行のお知らせ

Java、Eclipse、JUnit関連のエントリーは http:/

iOS8開発者向けお勧め本紹介[詳細! Swift iPhoneアプリ開発 入門ノート Swift 1.1+Xcode 6.1+iOS 8.1対応]

iOS7開発者向けお勧め本紹介を以前に紹介させていただきまいたが、今回

Swift入門(Xcode6のXCTestフレームワークで学ぶ) 第二回「関数(メソッド)とクロージャーの利用方法」

前回はSwiftの概要をザックリと説明させていただきました。 今

→もっと見る

Optimization WordPress Plugins & Solutions by W3 EDGE
PAGE TOP ↑