在视图控制器之间发送时,NSUserDefaults键变为nil

时间:2015-12-09 00:53:13

标签: ios swift nsuserdefaults


我需要在两个视图控制器之间发送用户名,以便第二个视图控制器知道将消息发送给谁。我已经尝试过prepareForSegue,但是我发现传递的变量不能动态改变。我决定使用NSUserDefaults,它在我的开发过程中非常有效。今天,它停止了工作。我不认为我删除了任何内容或进行了更改,但NSUserDefaults不再可靠地携带两个视图控制器之间的值。每隔一段时间(可能是20%的时间?),该值将被正确传递。其余时间没有任何结果。
代码:
设置键:

func chooseFriend(sender: UIButton) {
        let requestIndex = sender.tag
        let friendChosen = self.friends.objectAtIndex(requestIndex) as! String
        NSUserDefaults.standardUserDefaults().setValue("thisisatest", forKey: "testKey")
        NSUserDefaults.standardUserDefaults().synchronize()
        self.performSegueWithIdentifier("toChat", sender: self)
    } 

注意:在viewDidLoad中,我设置了testKey =""
在新视图控制器上检索键:

override func viewDidLoad() {
        super.viewDidLoad()
        let theKey = NSUserDefaults.standardUserDefaults().valueForKey("testKey")
        print("The Key: \(theKey)")

        refreshTable()
        let swipe: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "dismissKeyboard")
        swipe.direction = UISwipeGestureRecognizerDirection.Down
        self.view.addGestureRecognizer(swipe)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil)
        testLabel.text = ""
        self.messages.addObject("Loading......")
    }

每次默认显示为空:键:可选()
我可以在设置后成功打印默认值,但是一旦我被调到下一个视图控制器,它就会消失...
如果其他人遇到此问题,请告诉我。
谢谢



兰迪的代码:

func chooseFriend(sender: UIButton) {
        let requestIndex = sender.tag
        let friendChosen = self.friends.objectAtIndex(requestIndex) as! String
        // Instantiate the second view controller via t's identifier in the storyboard
        if let secondViewController = self.storyboard?.instantiateViewControllerWithIdentifier("ChatVC") as? chatViewController {
            // Set the chosen friend
            secondViewController.friendChosen = friendChosen
            self.presentViewController(secondViewController, animated: true, completion: nil)
        }
    }

将此添加到destinationviewcontroller:

var friendChosen: String!

3 个答案:

答案 0 :(得分:0)

最终,这种类型的信息应该通过委托从视图控制器传递到模型中的视图控制器。这将是通过真正的MVC模式实现此行为的“适当”方式。

说完了;我认为最快的解决方法是不使用segues并一起避免NSUserDefaults

尝试以下方法......

func chooseFriend(sender: UIButton) {
    let requestIndex = sender.tag
    let friendChosen = self.friends.objectAtIndex(requestIndex) as! String
    // Instantiate the second view controller via it's identifier in the storyboard
    if let secondViewController = self.storyboard?.instantiateViewControllerWithIdentifier("SecondViewControllerIdentifier") as? SecondViewController {
        // Set the chosen friend
        secondViewController.friendChosen = friendChosen
        self.presentViewController(secondViewController, animated: true, completion: nil)
    }
}

并在SecondViewController添加以下属性。

var friendChosen: String!

在将值传递给目标视图控制器之前,请确保该值不为

答案 1 :(得分:0)

NSUserDefaults的方法是setObject:forKey:objectForKey:,而不是setValue:forKey:(或者查看特定对象类型的特殊方法,例如setBool:forKey:或{ {1}}(我认为没有字符串的自定义设置方法。))

名称中带有“value”的方法是KVC方法。

但是,正如Randy所说,使用应用程序模型是一种更好的方法,或者将信息直接传递给prepareForSegue中目标视图控制器中的属性。在这种情况下,使用NSUserDefaults不是我的第一个选择,也不是我的第二选择。

答案 2 :(得分:0)

看起来你已经在使用故事板,所以使用prepareForSegue这样传递信息应该很容易。

class DestinationVC : UIViewController {
  var destName : String!

  override func viewWillAppear(animated: Bool) {
    //configure UI with the destName
    self.label.text = destName
  }

}

class PresentingVC : UIViewController {

  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let destinationVC = segue.destinationViewController as? DestinationVC {
      destinationVC.destName = "Some String to Pass"
    }
  }
}

如前所述,NSUserDefaults并不理想。您还将失去类型安全性并依赖于NSUserDefaults中的键匹配字符串,而不是使用destinationVC上的var进行自动完成和编译器检查。限制数据保存位置以及可以更改数据的位置也是一种很好的做法。当用例非常局限时,在NSUserDefaults中存储某些内容将使编写焦点测试变得更加困难,并使其易于从应用程序中的任何类更改。这可能是一个边缘情况,但在您的应用程序中启动这样的模式可能会让您在将来面临各种各样的副作用错误。