kitoko552.memo

kitoko552のメモ

Arrayは値型でNSArrayは参照型

要点

  • Arrayは値型でNSArrayは参照型ですよって話です。
  • 変数の再代入やメソッドの引数に渡す際、Arrayの場合はコピーが渡され、NSArrayの場合は参照が渡される。
  • Arrayでもinoutを使えば参照渡しができる。

SwiftのArrayは値型

SwiftのArrayは値型です。
Array型の変数を異なる変数に代入するとコピーが渡されます。
なので、代入先の変数の中身を変えても代入元の変数には影響はありません。

let array1: [Int] = [1, 2, 3]
var array2 = array1
array2[0] = 10

print(array1) // [1, 2, 3]
print(array2) // [10, 2, 3]

NSArray (NSMutableArray) は参照型

一方、Objective-C時代から存在するNSArrayは参照型です。
もちろん、NSArrayを継承しているNSMutableArrayも参照型です。
NSArray型の変数を異なる変数に代入すると参照が渡されます。
なので、代入先の変数の中身を変えると代入元の変数も中身が変わります。

let array1: NSMutableArray = [1, 2, 3]
var array2 = array1
array2.replaceObjectAtIndex(0, withObject: 10)

print(array1) // [10, 2, 3]
print(array2) // [10, 2, 3]

メソッドでも同様

したがって、メソッドでも同様の挙動をします。
Array型でメソッド内で中身を変化させる場合は新しいArrayを返してあげなければいけません。

func replaceArray(array: [Int]) -> [Int] {
  var newArray = array
  newArray[0] = 10
  return newArray
}

let array: [Int] = [1, 2, 3]
let newArray = replaceArray(array)

print(newArray) // [10, 2, 3]

しかし、NSMutableArrayの場合は参照型なので、メソッド内で中身を変えてあげるだけで変数の中身が変わります。

func replaceArray(array: NSMutableArray) {
  array.replaceObjectAtIndex(0, withObject: 10)
}

let array: NSMutableArray = [1, 2, 3]
replaceArray(array)

print(array) // [10, 2, 3]

Array型でもinoutを使えば

滅多に使いませんが、Swiftのinoutを使えばArray型でもメソッドの引数に参照を渡すことができます。
メソッドの引数にinoutをつけるとその引数が値渡しではなく、参照渡しになるというものです。
これを利用すれば、Array型でもメソッド内で中身を変えてあげるだけで変数の中身を変えることは可能です。

func replaceArray(inout array: [Int]) {
  array[0] = 10
}

var array: [Int] = [1, 2, 3]
replaceArray(&array)

print(array) // [10, 2, 3]

ですが、特にこのように実装するメリットはないので知っておく程度でいいと思います。
大事なのは、Array型は値型でNSArrayは参照型だということです。

おわり