Objective-C NSMutableString 【初級編 第19回】

この記事は2013年1月20日に書かれたものです。内容が古い可能性がありますのでご注意ください。


Objective-C NSMutableString 【初級編 第19回】

可変文字列

前回NSStringクラスの文字列切り出しや文字列結合メソッドの一部を紹介しました。
ここまで使用していたNSStringはimmutableな文字列となっているため変更ができません。
不変のオブジェクトの場合、変更はできませんが参照しているオブジェクトがどこかで勝手に変更されることがなく、
オブジェクトの管理が楽になります。
しかしNSStringで文字列の結合などをする場合、元の文字列が格納されている領域に新しい文字が追加されるのではなく、
結合した文字列で別のオブジェクトを作成するような形となります。
メモリ上には元の文字と結合された文字の両方がある感じですね。

しかし、しばしば変更されるような文字列の場合、その都度新しい文字列オブジェクトが作成されるということになります。
結合などの処理の場合、新しい文字列オブジェクトは自動解放プールに登録されるためいずれ解放されますが、
それまではメモリを確保したままとなり、使用していないのに確保されているというメモリの無駄使いということになります。

そこで変更可能な文字列を扱うためのクラスとして「NSMutableString」クラスというものがあります。

NSMutableStringクラス

「NSMutableString」はクラス名を見てもわかるように、mutableな文字列となります。
このクラスはNSStringクラスを継承しているのでNSStringのメソッドも使用可能です。

文字列の結合でimmutableなNSStringとmutableなNSMutableStringの違いを比較してみることにします。
文字列の結合メソッドとしてNSMutableStringの方では「appendString」メソッドが用意されています。
– (void) appendString: (NSString*)aString

引数に指定した文字列を結合します。戻り値で新しい文字列が返ってくるわけではなく、レシーバーとなっているオブジェクトに
結合される形となります。

コードでの確認

では使用してみましょう。
今回は簡単なコードで確認してみます。

#import <Foundation/Foundation.h>
#import <Foundation/NSObject.h>
#import "Bmi.h"
#import "Person.h"
#import "Manage.h"

int main(void){

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSString *name = [NSString stringWithString:@"Yamada"];
    NSMutableString *name2 = [[NSMutableString alloc] initWithString:@"Suzuki"];

    printf("immutable:%pn",name);
    name = [name stringByAppendingString:@"Tarou"];
    printf("imutable:%pn",name);

    printf("mutable:%pn",name2);
    [name2 appendString:@"Tarou"];
    printf("mutable:%pn",name2);

    [pool drain];
    [name release];
    [name2 release];
    return 0;
}

13行目で作成したNSStringオブジェクトのアドレスを表示させています。
14行目はObjective-C 文字列操作,結合,切り出し 【初級編 第18回】で使用した結合メソッドで「Yamada」に「Tarou」を
結合して、新たにできた文字列をnameに格納しています。
15行目で再度nameのアドレスを表示させています。
結合前と結合後でオブジェクトのアドレスが変わっているのかどうかを確認しています。

17行目で作成したNSMutableStringオブジェクトのアドレスを表示させています。
18行目は上で紹介した「appendString」を使用して「Yamada」に「Tarou」を結合しています。
19行目で再度のアドレスを表示させています。

結果

結果は以下のようになります。
objc24-1

NSStringのほうは前にも説明したように結合された文字列は新しいオブジェクトとなるので、アドレスも異なったものに
なっています。「Yamada」と「YamadaTarou」の両方がメモリ上に残っているということになります。
NSMutableStringのほうは結合前と結合後でアドレスが変わっていません。「Suzuki」が「SuzukiTarou」に変わったと
いうことになります。

このようにNSMutableStringは可変の文字列を扱うことができます。
最初に決まった文字列から変更が行われないような場合は、NSStringを使用して、頻繁に変更が行われるような文字列の場合
NSMutableString使用するといったやり方でいいのではないでしょうか。

今回はNSStringを取り上げましたが、これ以外にも不変のオブジェクトと可変のオブジェクトに分かれているものがあります。
「NSData」と「NSMutableData」といったようなクラスがこれにあたります。
「mutable」がついているものが可変、ついてないものが不変ということになります。

まとめ

今回のまとめとしては
・NSStringでは文字が変わっているように見えて、実際は新しくできた別のオブジェクトを参照している
・NSStringで頻繁に文字を変更するとその分、新しいオブジェクトができるためメモリを食う可能性がある
・NSMutabeStringは可変の文字列であるため、元の文字が頻繁に変更される場合に適している
・NSMutableString以外にも可変、不変のクラスに分かれているものがある
といったところでしょうか。

  • このエントリーをはてなブックマークに追加

PAGE TOP