【iOS】Objective-C→ Swift のbefore/after で気になったメモ【順次更新中】

個人的に気になった程度の内容でございます

##NSArray → Array


【before】

```objc
NSMutableArray *list = [NSMutableArray new];
```


【after】

```swift
var list = [String]()
```
※型はStringに限らず。


```objc
//データの追加
list.append("hoge");

//取得
var str:String = list[0];

//置換
list[0] = "test"

//削除
list.removeAtIndex(0)

```

##NSDictionary → Dictionary


【before】

```objc
NSMutableDictionary *dic = [NSMutableDictionary new];
```


【after】

```objc
var dic = [String:String]()
```
※型はStringやIntegerに限らず。

データの挿入は、

```objc
dic["hoge"] = "test"
```


##if

【before】
bool値以外でもOK
※OKという表現も微妙な気が。

【after】
bool値以外NG(コンパイルエラー)

```objc

var x = 1

if x == 1 {
   //OK
}


if x  {
   //NG　コンパイルエラー
}

```

##switch

【before】
数字のみ

【after】
数字以外もOK (any kind of dataだそうで)
break 要らない
whereを使い、絞り込みも可能

```objc

var lang = "ja";

switch(lang){
   case "en":
      var msg = "lang is en"
   case "zk":
      var msg = "lang is zk"
   case let x where x.hasPrefix("j"):
      var msg = "lang is ja?"
      //ここ通る
      //whereを使い、条件判定が可能
   default:
      var msg = "default"
}


```

##数字 / 文字列 の相互変換

【before】

```objc

    //数値から文字列へ
    int x = 1;
    NSString *xstr = [NSString stringWithFormat:@"%d",1];
    NSNumber* y = @1;
    NSString *ystr = [y stringValue];

    //文字列から数値へ
    x = [xstr intValue];


```

【after】

```objc
var x = 1
var xstr = "\(x)"
//以下でも可
xstr = String(x);


// 以下考え方 誤り ここから 2014.06.09

// x = xstr.toInt()!
// ! を記述しないとコンパイルエラーになる
// toIntが失敗する(クラッシュ)可能性があるため、確定しなければならない？

// ここまで。


//toInt は、返り値が? Optional であるため、変数に格納する場合は、
//Optionalな変数に代入しないと、コンパイルエラーになる。
// !を使う事で回避できるが、コンパイラエラーを強制的に回避しているイメージがある。。

var y:Int? = xstr.toInt();


```



##クラス インスタンスの生成
[参考リンク](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-XID_26 "参考リンク")

【before】

```objc
NSObject *obj = [NSObject new];

CGRect frame = CGRectMake(0,0,320,480);
UIView  *view = [UIView alloc]initWithFrame:frame];

```

【after】

```objc
var obj = NSObject()

var frame = CGRect(x:0.0, y:0.0, width:320.0, height:480.0)
var view = UIView(frame: frame)

```

##for

【before】

```objc

    for(int i= 0;i<5;i++) {
        NSLog(@"for %d",i);
    }

    NSArray *ary = @[@"hoge1",@"hoge2",@"hoge3",@"hoge4"];
    for(id item in ary) {
        NSLog(@"for ary %@",item);
    }
    
    NSDictionary *dic = @{@"key1":@"val1",@"key2":@"val2",@"key3":@"val3"};
    for (id key in dic) {
        NSLog(@"for dic %@",key);
        
    }

```

【after】

```objc

for _ in 0..5{
    println("for ")
}

var ary = ["hoge1","hoge2","hoge3"]
for item in ary{
    println("for ary " + item);
}

var dic = ["key1":"val1","key2":"val2","key3":"val3"]
for (key,val) in dic{
    println("for dic " + key + val);
}

var str = "hogehoge"
for c in str{
    //一文字ずつ
    println("for character " + c);
}

```

##関数 その1 インスタンスメソッド

ちょっと長くなりそうだったので。

【before】
<del>※blockと比較すべきかもしれませんが。</del>
インスタンスメソッドの比較としてまずは。

```objc

-(void)hoge {
    NSLog(@"引数無し、返り無し");
}

-(void)hoge:(NSString*)str {
    NSLog(@"引数1つ、返り有り");
}

-(void)hoge:(NSString*)str second:(NSString*)str2{
    NSLog(@"引数2つ、返り有り %@",str2);
    NSLog(@"引数3つ以上であれば、同じように増えていく");
}


-(NSString*)hoge2 {
    NSLog(@"返り有り");
    return @"hoge";
}

```


【after】

```objc

func hoge(){
    println("引数無し、返り値なし")
}

func hoge(str:String){
    println("引数一つ、返り値  " + str)
}

//objective-cと同様、第一引数においては、 external nameは不要
//第二引数は、 external nameが必要だが、
//メソッド内での変数名と同様になるため、str2が有効
//呼びもとでは、 hoge("test",str2:"test2") 
//となる。
func hoge(str:String,str2:String){
    println("引数二つ、返り値  " + str + str2)
}

func hoge2()->String{
    println("返り有り");
    return "hoge2";
}


```

##Optionals(?),Implicitly Unwrapped Optionals(!) 及び nilについての考察 その1

※The Swift Programing Language の73ページあたりに
conceptなども含めて記述されている。

ちょっと長くなりそうな気がしたので、その1

【before】
そもそも ? や !という表現はなかった

```objc

NSString *str = @"xxx";
//こういう記述はコンパイル上問題はない
str = nil;

```

【after】
まずswiftにおける前提として通常定義した変数に対して
nilを代入する事はコンパイルエラーとなり許容されていない。

```objc

var x:String = "xxx"
//コンパイルエラー
x = nil

```

また、nilとなりうるもの(これがいわゆるOptionals)
についても代入はNGとなる。

```objc

func hogehoge()->String?{
    return nil
}

var x:String = "xxx"
//これもコンパイルエラー
x = hogehoge()

```

ただし、場合によっては、nilを格納したい(nilがありうる)という
パラメータも存在する。まさに、Optonalな。

そこで、

```objc

var x:String? = "xxx"
x = nil

```

とすることで、xはOptonalとなり、nilを許容されます。
※!でも可能。

ただ、
こちらも、73ページに書かれていますが、
Optionalsとは、その値が存在するか、全く存在しないか(nil)という事なので、
上記変数x一つに二つの意味を内包することになるかと思います。

記述の仕方として、以下は当然ダメ。型の指定が必要。


```objc

// これはコンパイルエラー
var y? = "yyy"
// Optional<T>のシンタックスシュガーであり、型の指定が必要。
// このあたりは、680ページあたりに。。

```


##Optionals(?),Implicitly Unwrapped Optionals(!) 及び nilについての考察 その2

まだしっくりこないので引き続き。


まず、その1にもありますが、
?については、nilもしくは、その値を保持している状態と考え、
wrappedされている状態と考えます。

!については、そのwrapped 状態を unwrappedするものと
考えます。(これらの単語がよくドキュメントに出てくるので意図的に出してます)

その2では、!も合わせて、考えてみます。

以下、3種類について検討します。

パターンA ?でも!でもない通常定義した変数。 nilはNG
例)var str:String

パターンB Optionals(?)な変数   nilはOK
例)var str:String?

パターンC Implicitly Unwrapped Optionals(!)な変数 nilはOK
例)var str:String!

A,B,Cそれぞれの組み合わせの一例を紹介しつつ
動きの確認をしたいと思います。

```objc

var a:String? = "aaa"
var b:String! = "bbb"

//コンパイルエラー
var c:String = a

//コンパイルOK
var d:String = b


```

となります。
上記よりコンパイルレベルでの話ですが、
?状態のものについては、パターンAの変数に代入する事はできません。
それは、?がnilの可能性もあるためです。※パターンAについてはnilはNGのため。

しかし、!については、値があるという確定の意味合いになり、
コンパイル上問題はなくなります。

ただし、!については、nilの値も入れる事が可能なので、

```objc

var b:String! = "bbb"
b  = nil
var d:String = b

```

なども可能ですが、実行時に落ちます。※パターンAの変数はnilは許容しないため。


まだ、? ! については更新が必要かと思いますので、
引き続き色々試してみたいと思います。

おそらく、Class や Structureでその役割を発揮するのではないかと
考えています。。

- - -


他にも気になる事があったので、そのあたり更新するかもしれません。


ひとまず以上でございます。