17112


Swiftで構造体をNSMutableArrayの要素として挿入したいのですが、  
オブジェクト型に変換する必要があるのでしょうか？

CGRectなどをNSNumberにして挿入するのと同様に  
できるのでしょうか？


CC BY-SA 3.0
2015-09-30T12:26:33.133
17109
2015-10-16T16:10:55.057
2015-10-16T16:10:55.057
5519
12297
question
swift
Swiftで構造体をNSMutableArrayの要素として挿入したいのですが、 オブジェクト型に変換する必要があるのでしょうか？


「オブジェクト型」がなんのことなのか、ちょっと理解できない面がありますが、`CGRect`が、そのままでは`NSMutableArray`の要素にならないことは、Swiftでも同様です。  
`CGRect`（C言語の構造体）を、インスタンス（Objective-C）にラップ（Wrap）するには、（`NSNumber`でなくて）`NSValue`クラスを使います。

[code]

    import UIKit
    
    // CGRectのオブジェクトを作成
    let rect1 = CGRect(x: 0.0, y: 0.0, width: 30.0, height: 30.0)
    let rect2 = CGRect(x: 0.0, y: 30.0, width: 30.0, height: 30.0)
    let rect3 = CGRect(x: 30.0, y: 0.0, width: 30.0, height: 30.0)
    let rect4 = CGRect(x: 30.0, y: 30.0, width: 30.0, height: 30.0)
    
    // CGRectのオブジェクトを、Objective-Cのインスタンスにラッピング
    let objcRect1 = NSValue(CGRect: rect1)
    let objcRect2 = NSValue(CGRect: rect2)
    let objcRect3 = NSValue(CGRect: rect3)
    let objcRect4 = NSValue(CGRect: rect4)
    
    // Objective-CのインスタンスをSwiftの配列に格納
    var newArray: [AnyObject] = [objcRect1, objcRect2, objcRect3, objcRect4]
    // Swiftの配列をNSArrayにキャスト（NSMutableArrayではない）
    var objcArray: NSArray = newArray as NSArray
    
    // 配列から2番目の要素を取りだす。
    let newObjcRect: NSValue = objcArray[1] as! NSValue
    // NSValueインスタンスから、CGRectをアンラップ（Unwrap）
    let newRect: CGRect = newObjcRect.CGRectValue()
    
[/code]

Objective-Cのクラスとブリッジすることがなければ、どう考えても`NS(Mutable)Array`を使うメリットはないですね。

* * *

`CGRect`のような既存の構造体ではなくて、新規にSwiftの構造体を作るのなら、構造体（`struct`）ではなくて、クラス（`class`）として定義すれば、`NS(Mutable)Array`のメンバーに直接することができます。

[code]

    import UIKit
    
    // MySizeというクラスを定義
    class MySize {
        var width: Float = 0.0
        var height: Float = 0.0
        
        init(width: Float, height: Float) {
            self.width = width
            self.height = height
        }
    }
    
    let size1 = MySize(width: 30.0, height: 30.0)
    let size2 = MySize(width: 40.0, height: 40.0)
    let size3 = MySize(width: 50.0, height: 50.0)
    let size4 = MySize(width: 60.0, height: 60.0)
    
    // クラスなら、NSMutableArrayのメンバーになる。
    var objcSizes = NSMutableArray(capacity: 4)
    objcSizes.addObject(size1)
    objcSizes.addObject(size2)
    objcSizes.addObject(size3)
    objcSizes.addObject(size4)
    
    // 配列から取り出しも、このとおり。
    if let theSize = objcSizes[1] as? MySize {
        let theWidth = theSize.width
    }
    
[/code]

同様のことを、構造体でやろうとすると、「Argument type 'MySize' does not conform to expected type
‘AnyObject'」というコンパイルエラーが出ます。


CC BY-SA 3.0
2015-09-30T13:32:34.913
17112
2015-10-01T05:59:27.170
2020-06-17T08:14:45.997
-1
7362
17109
answer