从 Cloudkit 加载空属性时代码崩溃 - 使用 Swift

Posted

技术标签:

【中文标题】从 Cloudkit 加载空属性时代码崩溃 - 使用 Swift【英文标题】:Code Crashes when loading an empty attribute from Cloudkit - using Swift 【发布时间】:2015-09-05 23:53:33 【问题描述】:

我正在尝试访问 CloudKit 中的记录值,这里是 MyPin,它有一个标题和副标题属性/字段值。 但是有时记录值可能是空的(这里是字幕),当我调用时它会在该行崩溃:

var tempS: String = Annot["Subtitle"] as! String

因为Annot["Subtitle"] 不存在...

当我这样做时

println(Annot["Subtitle"]) 

它返回零

但如果我这样做:

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

【问题讨论】:

【参考方案1】:

当你得到Annot["Subtitle"] 时,它会给你一个CKRecordValue? 返回,它的基类是NSObjectProtocol。因此,在您的情况下,该字段确实存在,但它不是字符串,因此请使用 as!字符串会使您的应用程序崩溃。由于该字段存在,CKRecordValue 不会为零。但是该字段的内容为零。当您打印该字段时,它将输出该字段的.description。在你的情况下,这是零。你可以试试这个代码吗:

if let f = Annot["Subtitle"] 
   print("f = \(f) of type \(f.dynamicType)")

然后在打印行上设置一个断点,当它停止时,在输出窗口中尝试以下三个语句:

po Annot
po f
p f

po Annot 之后,您应该会看到该记录中的内容。包括您的字幕字段。 po f 没那么有趣。它只会输出一个内存地址。 p f 但是会显示实际类型。如果它是一个字符串,你应该会看到类似:(__NSCFConstantString *) $R3 = 0xafdd21e0

附:也许您应该将其称为记录而不是 Annot。它是一个局部变量,所以它应该以小写字符开头。而且它仍然是记录而不是注释。

【讨论】:

【参考方案2】:

我认为你在做正确的事情,但是你看不到 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 有一些变化

【讨论】:

感谢您的回答,但运气不好,仍然没有打印出来:-(

以上是关于从 Cloudkit 加载空属性时代码崩溃 - 使用 Swift的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的应用在使用 cloudkit 时会崩溃?

由于尝试在空对象引用上调用虚拟方法“ ”,应用程序崩溃

设置类变量时代码崩溃

尝试为 NSError 设置本地化描述时代码崩溃

当我使用双向链表中的最后一个指针时代码崩溃

当派生类的析构函数是虚拟的而基类的 dtor 不是时代码崩溃