NSUserDefaults从其他线程中删除并设置对象

时间:2016-05-21 23:56:17

标签: swift nsuserdefaults

NSUserDefaults.standardUserDefaults() 我想了解为什么在从背景轮胎中移除对象然后使用主线程中的相同键添加对象之后,则无法再从主要线程再次设置它。这是一个错误吗?或者它是否按预期工作?

    let mykey = "nsDataKeyOne"
    let stringUno:NSString = "................."
    let dataOne = stringUno.dataUsingEncoding(NSUTF8StringEncoding)!
    let stringDos:NSString = "000000000000000000"
    let dataTwo = stringDos.dataUsingEncoding(NSUTF8StringEncoding)!
    let userDefaults = NSUserDefaults.standardUserDefaults()


    userDefaults.setObject(dataOne, forKey: mykey)

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), {
        userDefaults.removeObjectForKey(mykey)
    })

    userDefaults.setObject(dataOne, forKey: mykey)

    print(userDefaults.dataForKey(mykey))  // print nil, why?


    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), {
        userDefaults.setObject(dataTwo, forKey: mykey)
        print(userDefaults.dataForKey(mykey)) // there is data

    })

2 个答案:

答案 0 :(得分:4)

简短回答

您收到F_ID因为说明可能按以下顺序执行

nil

原因

首先,userDefaults.setObject(dataOne, forKey: mykey) userDefaults.setObject(dataOne, forKey: mykey) userDefaults.removeObjectForKey(mykey) print(userDefaults.dataForKey(mike)) 是线程安全的。因此,我们可以想象当没有另一个线程正在改变该值时,对给定键执行写操作。

执行此指令时

NSUserDefaults

另一个线程开始尝试将闭包添加到全局队列。当此线程正在等待访问全局队列时,代码的执行会继续执行,因此(可能)执行此行

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), {
        userDefaults.removeObjectForKey(mykey)
    })

此行会锁定userDefaults.setObject(dataOne, forKey: mike) ,直到NSUserDefaults被保存。

接下来,闭包最终在主队列中,它已准备好执行,所以

dataOne

最后是印刷品

userDefaults.removeObjectForKey(mike)

答案 1 :(得分:2)

不,这不是一个错误。 } userDefaults.removeObjectForKey(mykey)队列在{/ 1>}第二次调用DISPATCH_QUEUE_PRIORITY_HIGH之后很可能已经setObject(dataOne, forKey: mykey)执行了dispatch_async所以它已经被删除了dispatch_sync你打算把它打印出来的时间。

如果您将第一个port install <name of package> port selfupdate 更改为{{1}},则会在打印时看到数据。