从 Cloudkit 加载空属性时代码崩溃 - 使用 Swift
Code Crashes when loading an empty attribute from Cloudkit - using Swift
我正在尝试访问 CloudKit 中的记录值,这里是 MyPin,它有一个标题和副标题 attribute/field 值。
然而,有时记录值为空(此处为副标题)可能会发生,当我调用时它会在该行崩溃:
var tempS: String = Annot["Subtitle"] as! String
因为Annot["Subtitle"]
不存在...
当我做
println(Annot["Subtitle"])
它returns无
但如果我这样做 :
if (Annot["Subtitle"] == nil) {
println("just got a nil value")
}
我从不输入if语句:
谁能帮我判断记录是否为空值?
这是我的代码行:
let container = CKContainer.defaultContainer()
let publicData = container.publicCloudDatabase
let query = CKQuery(recordType: "MyPin", predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray: nil))
publicData.performQuery(query, inZoneWithID: nil) { results, error in
if error == nil { // There is no error
for Annot in results {
var tempS: String = Annot["Subtitle"] as! String
}}
我认为您做的是对的,但是您没有看到 println,因为它是在另一个线程中执行的(完成部分是异步执行的)。
试试这个:
if (Annot["Subtitle"] == nil) {
dispatch_async(dispatch_get_main_queue()) {
println("just got a nil value")
}
}
看看它是否有效!
我从cloudkit获取值的方式是这样的。这两者都处理了 nil 值和所有其他可能发生的情况。请注意,我已经实现了一个委托来将我的结果异步返回给调用对象
privateDB.performQuery(query, inZoneWithID: nil) { (result, error) -> Void in
if error == nil{
for record in result{
let rec = record as! CKRecord
if let xxxVar = rec.valueForKey("fieldName") as? String{
myArray.append( xxxVar! ) //append unwrapped xxxVar to some result or whatever
}else{
//handle nil value
}
}
dispatch_async(dispatch_get_main_queue()) {
//do something with you data
self.delegate?.myResultCallBack(myArray)
return
}
}else{
dispatch_async(dispatch_get_main_queue()) {
self.delegate?.myErrorCallBack(error)
return
}
}
}
注意,Swift2 中有一些变化
当你得到 Annot["Subtitle"]
时,它会给你一个 CKRecordValue?
return,它的基数 class 为 NSObjectProtocol
。因此,在您的情况下,该字段确实存在,但它不是字符串,因此可以使用 as!字符串会使您的应用程序崩溃。由于该字段存在,因此 CKRecordValue
不会为零。但是该字段的内容为零。当您打印该字段时,它将输出该字段的 .description
。在你的情况下是零。你能试试这个代码吗:
if let f = Annot["Subtitle"] {
print("f = \(f) of type \(f.dynamicType)")
}
然后在打印行上设置一个断点,当它停止时在输出中尝试以下三个语句 window:
po Annot
po f
p f
在 po Annot
之后,您应该会看到该记录中的内容。包括您的字幕字段。 po f
没那么有趣。它只会输出一个内存地址。 p f
但是会显示实际类型。如果它是一个字符串,您应该会看到类似这样的内容:(__NSCFConstantString *) $R3 = 0xafdd21e0
P.S。也许你应该称它为记录而不是注释。它是一个局部变量,所以它应该以小写字符开头。而且它仍然是一个记录,而不是一个注释。
我正在尝试访问 CloudKit 中的记录值,这里是 MyPin,它有一个标题和副标题 attribute/field 值。 然而,有时记录值为空(此处为副标题)可能会发生,当我调用时它会在该行崩溃:
var tempS: String = Annot["Subtitle"] as! String
因为Annot["Subtitle"]
不存在...
当我做
println(Annot["Subtitle"])
它returns无
但如果我这样做 :
if (Annot["Subtitle"] == nil) {
println("just got a nil value")
}
我从不输入if语句:
谁能帮我判断记录是否为空值?
这是我的代码行:
let container = CKContainer.defaultContainer()
let publicData = container.publicCloudDatabase
let query = CKQuery(recordType: "MyPin", predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray: nil))
publicData.performQuery(query, inZoneWithID: nil) { results, error in
if error == nil { // There is no error
for Annot in results {
var tempS: String = Annot["Subtitle"] as! String
}}
我认为您做的是对的,但是您没有看到 println,因为它是在另一个线程中执行的(完成部分是异步执行的)。 试试这个:
if (Annot["Subtitle"] == nil) {
dispatch_async(dispatch_get_main_queue()) {
println("just got a nil value")
}
}
看看它是否有效!
我从cloudkit获取值的方式是这样的。这两者都处理了 nil 值和所有其他可能发生的情况。请注意,我已经实现了一个委托来将我的结果异步返回给调用对象
privateDB.performQuery(query, inZoneWithID: nil) { (result, error) -> Void in
if error == nil{
for record in result{
let rec = record as! CKRecord
if let xxxVar = rec.valueForKey("fieldName") as? String{
myArray.append( xxxVar! ) //append unwrapped xxxVar to some result or whatever
}else{
//handle nil value
}
}
dispatch_async(dispatch_get_main_queue()) {
//do something with you data
self.delegate?.myResultCallBack(myArray)
return
}
}else{
dispatch_async(dispatch_get_main_queue()) {
self.delegate?.myErrorCallBack(error)
return
}
}
}
注意,Swift2 中有一些变化
当你得到 Annot["Subtitle"]
时,它会给你一个 CKRecordValue?
return,它的基数 class 为 NSObjectProtocol
。因此,在您的情况下,该字段确实存在,但它不是字符串,因此可以使用 as!字符串会使您的应用程序崩溃。由于该字段存在,因此 CKRecordValue
不会为零。但是该字段的内容为零。当您打印该字段时,它将输出该字段的 .description
。在你的情况下是零。你能试试这个代码吗:
if let f = Annot["Subtitle"] {
print("f = \(f) of type \(f.dynamicType)")
}
然后在打印行上设置一个断点,当它停止时在输出中尝试以下三个语句 window:
po Annot
po f
p f
在 po Annot
之后,您应该会看到该记录中的内容。包括您的字幕字段。 po f
没那么有趣。它只会输出一个内存地址。 p f
但是会显示实际类型。如果它是一个字符串,您应该会看到类似这样的内容:(__NSCFConstantString *) $R3 = 0xafdd21e0
P.S。也许你应该称它为记录而不是注释。它是一个局部变量,所以它应该以小写字符开头。而且它仍然是一个记录,而不是一个注释。