web-dev-qa-db-ja.com

in Swift:Array VS NSArray VS [AnyObject]の違い

タイトルにあるように、Array vs NSArray vs [AnyObject]の違いは何ですか?

また、これにアプローチする最も推奨される方法は何ですか。私が推奨することは、最も簡単な実装は何かということです。ありがとうございました。

34
shle2821

Arraystructであるため、Swiftではvalue typeです。 NSArrayは不変のObjective C クラスです。したがって、参照型 in Swiftであり、Array<AnyObject>NSMutableArrayは、NSArrayの可変サブクラスです。

var arr : NSMutableArray = ["Pencil", "Eraser", "Notebook"]
var barr = ["Pencil", "Eraser", "Notebook"]

func foo (var a : Array<String>)
{
    a[2] = "Pen"
}

func bar (a : NSMutableArray)
{
    a[2] = "Pen"
}

foo(barr)
bar(arr)

println (arr)
println (barr)

プリント:

(
    Pencil,
    Eraser,
    Pen
)
[Pencil, Eraser, Notebook]

fooaのローカル値を変更し、barは参照を変更するためです。他の参照型のようにvarの代わりにlet arrを行う場合にも機能します。

58
Krzak

ArrayはSwift構造体であり、一般的な構造体です。つまり、任意の特定の型(Int、String、AnyObjectなど)の配列になります)

[T]Array<T>の構文糖衣です

AnyObjectは、Objective-Cクラスを含む任意のクラスのオブジェクトです。

NSArrayは、Objective-Cオブジェクトを保持できるObjective-C構造体であり、Array<AnyObject>との間で透過的にマッピングされます。

21
David Berry

Krzakの答えを使用して、実際の例を次に示します。

// Let´s create an Array as a struct showing alternative ways
    var arrStruct = ["Pencil", "Eraser", "Notebook"]
    // or var arrStruct: [String] = ["Pencil", "Eraser", "Notebook"]
    // or var arrStruct: Array = ["Pencil", "Eraser", "Notebook"]
    // or var arrStruct = Array(["Pencil", "Eraser", "Notebook"])
    // All this alternative ways create an array as struct

    // Now let´s create a function that modifies this array struct
    func modifyArr(alternativeArr: [String]) 
    // or func modify(alternativeArr: Array<String>)
    {
        alternativeArr[2] = "Pen" // compilation error
        // This won´t work. In Swift >= 3.0 all func parametes are a let variable, 
        // this means alternativeArr is defined as a let. What one has to do is 
        // create a local variable and copy the value.

        var localAlternativeArr = alternativeArr
        // or var localAlternativeArr: [String] = alternativeArr
        // or var localAlternativeArr: Array = alternativeArr

        // now we can change it.
        localAlternativeArr[2] = "Pen"
        print(localAlternativeArr) // ["Pencil", "Eraser", "Pen"]
        print(alternativeArr) // ["Pencil", "Eraser", "Notebook"]
    }

    modifyArr(alternativeArr: arrStruct)
    print(arrStruct) // ["Pencil", "Eraser", "Notebook"]

    // Since the arrStruct is a struct every time we assign to another variable or 
    // pass it as a func argument a copy is made.



// Now let´s create as an NSMutableArray
    var arrClass: NSMutableArray = ["Pencil", "Eraser", "Notebook"]
    // or var arrStruct = NSMutableArray(array: ["Pencil", "Eraser", "Notebook"])
    // All this create an NSMutableArray as a class

    // Now let´s create a function that modifies this array struct
    func modifyArr(alternativeArr: NSMutableArray)
    {
        alternativeArr[2] = "Pen"
        print(alternativeArr)
        // (
        //   Pencil,
        //   Eraser,
        //   Pen
        // )
    }

    modifyArr(alternativeArr: arrClass)
    print(arrClass)
    // (
    //   Pencil,
    //   Eraser,
    //   Pen
    // )

    // Since the arrClass is a class everytime we assign to another variable or 
    // pass it as a func argument is passed by reference. Means that any change
    // inside modifyArr is going to change the arrClass outside. The change 
    // is made in the same pointer.
1
lopes710

@Krzakの優れた答えに加えて、これが理由です

print(NSArray().object(at: 1))   // Triggers an UnmanagedException

2018-11-09 11:38:08.798088-0600 AppName [38786:10497909] *キャッチされない例外 'NSRangeException'によるアプリの終了、理由: '*-[__ NSArray0 objectAtIndex:]:インデックス1以降空のNSArrayの境界 '

そして

print(Array<Int>()[1])  // Halts with "Thread 1: Fatal error: Index out of range"

エラーのこの異なる処理は、違いを理解するのに役立ちました..... e

0
eharo2