しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

SwiftのStringとNSStringとBridgeについて

SwiftのString型についてまとめてみました。

Objective-cのNSStringよりイケてる所

@を付けなくて済む

let str = "" // @""と書く必要がなくなりました。

文字列連結が楽

+で連結できるようになりました、直感的で分かりやすい。

let str = "A" + "B" // Objective-cでは[@"" stringByAppendingString:@""];でした

文字列への埋め込みも楽

文字列中で\()と書くだけで文字列中に変数を埋め込めるようになりました。

let num = 1
let str = "AAA\(num)" // Objective-cは[NSString stringWithFormat:@"AAA%d", num];

フォーマット指定の文字列生成は下の通りです。

String(format: "%03d", 1.0) // → 1.00になる、Objective-cは[NSString stringWithFormat:@"%03d", 1.0];

文字列比較も簡単

==だけで比較できるようになりました。

if "AAA" == "AAA" {} // Objective-cでは[@"AAA" isEqualToString:@"AAA"];

String型について

SwiftのString型ですが、実はクラスでなく構造体です。
Stringの定義を見ると下のようになっています。

struct String {
    init()
}

その為letを使った変数に対しては破壊的メソッドを呼び出せなくなっています。

let str = String("AAA")
str.append(Character("A")) // これはエラーになる

let a = NSMutableString(string: "A")
a.appendString("SSS") // NSMutableStringはクラスなのでエラーにならない。

StringとNSStringの違い

使えるメソッドに差があります。
toIntメソッドisEmptyプロパティーなど、Objetive-cでなかったものはNSStringでは使えませんでした。
逆にisEqualToStringメソッドはNSStringにしかありませんでした。
深くは追いかけてないのですが、細かい所を見ていくと他にも多くの違いがあるのではないかと思います。

Objective-cの返り値NSStringのメソッドを呼ぶとどうなるか

SwiftObjective-cの両方を使っている時にどうなるかを調べてみました。
まずは下のようにObjective-cのクラスを用意します。

@interface Test : NSObject
- (NSString*)str;
@end
@implementation Test
- (NSString*)str { return @"a"; }
@end

それをSwiftから呼び出してString型にしかないメソッドをCallしてみます。

let str = Test().str()
println(str.isEmpty) // → false

そうすると実際にメソッド呼び出しが成功します。
つまりNSStringはStringに変換されるのかと思ったのですが、実はこの変数は下のようにアンラップができます。

let str = Test().str()
println(str!.isEmpty) // → false

どうも普通のStringとは違うようです。
中身を見るためにこの変数をprintしてみると下のような結果になりました。

let str = Test().str()
println(str) // → 
println("A") // → A
println(NSString(string: "A")) // → A

strのprintした結果は空っぽでした。
どうもStringともNSStringとも違うものが入っているようです。
今回の調査はここまでにしますが、何が入っているか興味深いですね。

まとめ

Objective-cの返り値NSStringのメソッドはStringっぽいものを返してくれると覚えていれば良さそうです。
ただしnilが返ってくる可能性があるのでその点については要注意です。
String自体については全体的に便利になっていて嬉しいです。