0

我正在将应用程序转换为 swift3 并遇到以下问题。

@objc required init(response: HTTPURLResponse, representation: [NSObject : AnyObject])
{
    if (representation.value(forKeyPath: "title") is String)    {
        self.title = **representation.value**(forKeyPath: "title") as! String
    }

我收到以下错误:

[NSObject:AnyObject] 类型的值没有成员值。

在旧版本的代码中,我只是使用 AnyObject 作为表示的类型,但如果我这样做,我会在AnyObject is not a subtype of NSObject那里得到错误:

if (representation.value(forKeyPath: "foo") is String) {
    let elementObj = Element(response: response, representation:**representation.value(forKeyPath: "foo")**!)
}
4

1 回答 1

0

您正在混合使用 Objective-C 和 Swift 风格。最好实际决定。

桥接NSDictionary不是自动的。

考虑:

let y: [NSObject: AnyObject] = ["foo" as NSString: 3 as AnyObject] // this is awkward, mixing Swift Dictionary with explicit types yet using an Obj-C type inside
let z: NSDictionary = ["foo": 3]
(y as NSDictionary).value(forKeyPath: "foo") // 3
// y["foo"] // error, y's keys are explicitly typed as NSObject; reverse bridging String -> NSObject/NSString is not automatic
y["foo" as NSString] // 3
y["foo" as NSString] is Int // true
z["foo"] // Bridging here is automatic though because NSDictionary is untyped leaving compiler freedom to adapt your values
z["foo"] is Int // true
// y.value // error, not defined

// Easiest of all:
let ynot = ["foo": 3]
ynot["foo"] // Introductory swift, no casting needed
ynot["foo"] is Int // Error, type is known at compile time

参考:

https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html

请注意显式使用'as'required 来String返回NSString. 桥接不是隐藏的,因为他们希望您使用值类型 ( String) 而不是引用类型 ( NSString)。所以这是故意更麻烦的。

与引用类型相比,值类型的主要优势之一是它们更容易推理您的代码。有关值类型的更多信息,请参阅 Swift 编程语言 (Swift 3) 中的类和结构,以及 WWDC 2015 session 414 Building Better Apps with Value Types in Swift。

于 2016-09-23T18:11:50.523 回答