18

NSNotificationCenter.defaultCenter().postNotificationName userinfo は、AnyObject プロトコルに準拠したデータを含む辞書のみを受け入れるため、構造体を NSNotification の一部として投稿する方法について何か提案はありますか?

私の最初の考えは、構造体をクラスにラップすることですが、そもそも構造体を使用するポイントは何でしょうか。

何か不足していますか、それとも Swift を Objective C 用に構築された API と混同した結果ですか?

これが私が説明していることのデモンストレーションです: -

class wrapper: NSObject {

  var aStructToWrap: aStruct

  init(theStruct: aStruct) {

    aStructToWrap = theStruct

    super.init()
  }

}

struct aStruct {
    var aValue: String
}

let aRealStruct = aStruct(aValue: "egg")


NSNotificationCenter.defaultCenter().postNotificationName("aKey", object: nil, userInfo: ["anotherKey": aRealStruct]) // ERR: Extra argument 'userinfo' in call

let wrappedStruct = wrapper(theStruct: aRealStruct)

NSNotificationCenter.defaultCenter().postNotificationName("aKey", object: nil, userInfo: ["anotherKey": wrappedStruct]) // no error
4

1 に答える 1

31

問題は、元の Obj-C メソッドが NSDictionary を必要とすることです。NSDictionary は、NSObject にある isEqual: とそのキーを比較することを好みますが、Swift では [AnyObject: AnyObject] に変換されます。プロトコルであるため、キーは NSObject でなければなりません (NSObjectProtocol で十分かどうかはわかりませんが、Apple はそれを NSObject にすることにしました)。したがって、Swift では NSDictionary userInfo は [NSObject: AnyObject] である必要があるため、そこに構造体を配置することはできず、Objective-C でもできるとは思いません。

悲しいことに、ラッパーが必要になります。NSValue をいじって、醜く非効率的なものを作成することもできますが、いずれにせよ、最善の解決策は作成したラッパーです。

ただし、必要のない NSObject のサブクラスを作成したので、そのコードを捨てることができます:)

class Wrapper {
    var aStructToWrap: aStruct
    init(theStruct: aStruct) {
        aStructToWrap = theStruct
    }
}


struct aStruct {
    var aValue: String
}

私たちがもっとうまくやれることを除いて!任意の構造体または値 (またはオブジェクト) の汎用ラッパーを作成できます。

class Wrapper<T> {
    var wrappedValue: T
    init(theValue: T) {
        wrappedValue = theValue
    }
}

struct aStruct {
    var aValue: String
}

let aRealStruct = aStruct(aValue: "egg")

let wrappedStruct = Wrapper(theValue: aRealStruct)

NSNotificationCenter.defaultCenter().postNotificationName("aKey", object: nil, userInfo: ["anotherKey": wrappedStruct]) // no error

これは変更可能なラッパーです。let の var を切り替えて不変にしてください。

于 2015-04-25T13:34:30.337 に答える