条件绑定的初始化程序必须具有 Optional 类型,而不是 'AnyObject - Approach
Initializer for conditional binding must have Optional type, not 'AnyObject - Approach
以下代码会抛出一条消息 "Initializer for conditional binding must have Optional type, not 'AnyObject'"
func parseData2(){
var data:NSData?
if let data2 = data {
do {
let details = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let actualDetails = details where actualDetails.isKindOfClass(NSDictionary) {
print("Parse Data")
}
}catch {
print("Error \(error)")
}
}
}
为了解决上述错误,我使用了以下代码。
func parseData2(){
var data:NSData?
if let data2 = data {
do {
let details:AnyObject = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let actualDetails:AnyObject = details where actualDetails.isKindOfClass(NSDictionary) {
print("Parse Data")
}
}catch {
print("Error \(error)")
}
}
}
是否有比上述更好的方法,否则我的代码可能会崩溃?
考虑到 nil check、type check 然后 type cast,我还想添加一个代码检查。 Swift 提供了很大的灵活性,但解决问题有点困难。假设我有一本字典 cityDetails,我正在尝试获取 self.cityZipCode 和 self.cityIdentifier 的数据,它们是可选的,定义为 var cityZipCode:Int ?和 var cityIdentifier:Int?
if let cityBasic = cityDetails["basicDetails"] where
cityBasic!.isKindOfClass(NSDictionary) {
self.cityZipCode = (cityBasic as! NSDictionary)["zip"].integerValue ?? 0
self.cityIdentifier = (cityBasic as! NSDictionary)["cityId"].integerValue ?? 0
}
无需解包 try
的结果。它不是可选的。您确实需要将结果从 try
转换为 NSDictionary
。使用as?
向下转型。
最佳实践:完全访问返回的错误以进行良好的错误处理
func parseData2(){
var data:NSData?
if let data2 = data {
do {
let details = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let detailsDict = details as? NSDictionary {
print("Parse Data")
} else if let detailsArray = details as? NSArray {
print("array")
}
} catch {
print("Error \(error)")
}
}
}
快速而肮脏:错误处理不适合我!
func parseData2(){
var data:NSData?
if let data2 = data {
let details = try? NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let detailsDict = details as? NSDictionary {
print("Parse Data")
} else {
print("details might be nil, or not an NSDictionary")
}
}
}
糟糕模式:崩溃是特征
func parseData2(){
var data:NSData?
if let data2 = data {
let details = try! NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments) as! NSDictionary
}
}
关于多个解包的一些额外信息:
将下面的代码放在操场上。
struct SomeStruct {
var anOptional : Int?
init() {
}
}
func unwrapWithIfLet() {
if let unWrappedStruct = myStruct, let unWrappedSomething = unWrappedStruct.anOptional {
print("multiple optional bindings succeeded")
// both unWrappedStruct and unWrappedSomething are available here
} else {
print("something is nil")
}
}
func unwrapWithGuard() {
guard let unWrappedStruct = myStruct, let unWrappedSomething = unWrappedStruct.anOptional else {
print("something is nil")
return
}
print("multiple optional bindings succeeded")
// both unWrappedStruct and unWrappedSomething are available here
}
var myStruct : SomeStruct?
//unwrapWithGuard()
//unwrapWithIfLet()
myStruct = SomeStruct()
myStruct!.anOptional = 1
unwrapWithGuard()
unwrapWithIfLet()
您正在寻找 as?
,它试图将左边的东西转换为右边的类型,如果无法转换,则 returns nil:
let details = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let actualDetails = details as? NSDictionary {
print("Parse Data")
}
您很少需要在 Swift 中使用 isKindOfClass
。如果您发现自己在使用它,问问为什么,并考虑 as
或 as?
是否会起作用。
以下代码会抛出一条消息 "Initializer for conditional binding must have Optional type, not 'AnyObject'"
func parseData2(){
var data:NSData?
if let data2 = data {
do {
let details = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let actualDetails = details where actualDetails.isKindOfClass(NSDictionary) {
print("Parse Data")
}
}catch {
print("Error \(error)")
}
}
}
为了解决上述错误,我使用了以下代码。
func parseData2(){
var data:NSData?
if let data2 = data {
do {
let details:AnyObject = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let actualDetails:AnyObject = details where actualDetails.isKindOfClass(NSDictionary) {
print("Parse Data")
}
}catch {
print("Error \(error)")
}
}
}
是否有比上述更好的方法,否则我的代码可能会崩溃?
考虑到 nil check、type check 然后 type cast,我还想添加一个代码检查。 Swift 提供了很大的灵活性,但解决问题有点困难。假设我有一本字典 cityDetails,我正在尝试获取 self.cityZipCode 和 self.cityIdentifier 的数据,它们是可选的,定义为 var cityZipCode:Int ?和 var cityIdentifier:Int?
if let cityBasic = cityDetails["basicDetails"] where
cityBasic!.isKindOfClass(NSDictionary) {
self.cityZipCode = (cityBasic as! NSDictionary)["zip"].integerValue ?? 0
self.cityIdentifier = (cityBasic as! NSDictionary)["cityId"].integerValue ?? 0
}
无需解包 try
的结果。它不是可选的。您确实需要将结果从 try
转换为 NSDictionary
。使用as?
向下转型。
最佳实践:完全访问返回的错误以进行良好的错误处理
func parseData2(){
var data:NSData?
if let data2 = data {
do {
let details = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let detailsDict = details as? NSDictionary {
print("Parse Data")
} else if let detailsArray = details as? NSArray {
print("array")
}
} catch {
print("Error \(error)")
}
}
}
快速而肮脏:错误处理不适合我!
func parseData2(){
var data:NSData?
if let data2 = data {
let details = try? NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let detailsDict = details as? NSDictionary {
print("Parse Data")
} else {
print("details might be nil, or not an NSDictionary")
}
}
}
糟糕模式:崩溃是特征
func parseData2(){
var data:NSData?
if let data2 = data {
let details = try! NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments) as! NSDictionary
}
}
关于多个解包的一些额外信息: 将下面的代码放在操场上。
struct SomeStruct {
var anOptional : Int?
init() {
}
}
func unwrapWithIfLet() {
if let unWrappedStruct = myStruct, let unWrappedSomething = unWrappedStruct.anOptional {
print("multiple optional bindings succeeded")
// both unWrappedStruct and unWrappedSomething are available here
} else {
print("something is nil")
}
}
func unwrapWithGuard() {
guard let unWrappedStruct = myStruct, let unWrappedSomething = unWrappedStruct.anOptional else {
print("something is nil")
return
}
print("multiple optional bindings succeeded")
// both unWrappedStruct and unWrappedSomething are available here
}
var myStruct : SomeStruct?
//unwrapWithGuard()
//unwrapWithIfLet()
myStruct = SomeStruct()
myStruct!.anOptional = 1
unwrapWithGuard()
unwrapWithIfLet()
您正在寻找 as?
,它试图将左边的东西转换为右边的类型,如果无法转换,则 returns nil:
let details = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let actualDetails = details as? NSDictionary {
print("Parse Data")
}
您很少需要在 Swift 中使用 isKindOfClass
。如果您发现自己在使用它,问问为什么,并考虑 as
或 as?
是否会起作用。