从.plist检索的Objective-C样式在Swift中不起作用?

时间:2015-12-08 11:02:53

标签: ios objective-c swift plist

每当我的视图通过以下方法加载时,我就是在Objective-C中的.plist中检索数据 -

@interface ListTableViewController ()

@end

@implementation ListTableViewController
NSArray *dict;

-(void)viewDidAppear:(BOOL)animated
{
    NSString *arr= [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

    arr=[arr stringByAppendingPathComponent:@"datalist.plist"];
    if ([[NSFileManager defaultManager]fileExistsAtPath:arr])
    {
       dict=[NSArray arrayWithContentsOfFile:arr];
        NSLog(@"%@",dict);

    }
    [self.tableView reloadData];

}

现在对于Swift我做的事与 -

相同
class ListTableViewController: UITableViewController{
  var arr = NSArray()
  var plistfinalpath = String()

  override func viewDidAppear(animated: Bool){
      let path = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, .UserDomainMask, true)[0]
      plistfinalpath = path.stringByAppendingString("/login.plist")
      print(plistfinalpath)
      print("time of appearing\(arr)")

      arr = NSArray(contentsOfFile: plistfinalpath)!
      self.tableView.reloadData()
  }
}

但是,当第一次启动应用程序时,当plist为空时我必须打开行arr = NSArray(contentsOfFile: plistfinalpath)!中的值,因为我打开它,因此显示错误。那么我怎样才能实现我在目标C中所做的工作呢?

3 个答案:

答案 0 :(得分:4)

完整的答案涉及理解“可选”的概念。

什么是可选项?

在Swift中,您可以将变量声明为可选,在类型后面附加?。执行此操作时,表示变量可以保存值或根本不保存值。当您将变量声明为非可选变量时,编译器会确保它始终保持一个值。

  • 将变量声明为可选:var myOptionalVariable: NSArray?
  • 将变量声明为不可选:var myVariable = NSArray()

注意在非可选var中,我们被编译器强制给它一个值(在这种情况下只是一个空数组)。这是因为编译器授予当变量不是可选的时,它在每个时刻都保存一个值。 注意区别:第一个语句只是声明变量作为可选的 NSArray ,第二个语句初始化并分配一个新的空 NSArray 变量。

为什么选项有用?

随着选项的引入,我们有关于变量中包含的数据存在的编译时安全性。当不使用可选变量时,我们确信变量始终保持值。同时,当使用可选变量时,我们不得不处理可能不存在值的情况,而不是静默处理它(这就是在objective-c中nil发生的情况) 。从可选项中提取值称为展开

展开选项(即从可选中提取值)

要从可选变量中“提取”该值,您需要将其解包。有几种方法可以打开一个可选项,给定myOptional是一个可选变量,这里有一些例子:

if let variable = myOptional { 
    // I can safely use variable here
}

甚至是其他语法:

variable = myOptional ?? defaultNonOptionalValue
// I can safely use variable here

此外,您可以使用

强制解包
variable = myOptional!
// crash incoming?

你用这种方式进行解包,但实际上你是在对编译器说“相信我,我知道myOptional永远不会是”在你的情况下是不正确,它会导致错误Fatal error: unexpectedly found nil while unwrapping an Optional values崩溃。你应该总是避免强制解包,除非你真的确定你的数据。

长话短说

您有两个可行的解决方案:

  • 不要使用强制解包(请参阅上面关于展开的选项)
  • 将变量arr转换为可选(通过以这种方式声明它:var arr: NSArray?),然后在使用它时处理(非强制)展开(即在tableView数据源方法中) )

哪一个更适合您的情况,取决于arr含义,如果有意义是可选的,那么去吧,否则,只是让它不可选并指定一些默认值。

答案 1 :(得分:1)

只需将arr变量定义为可选,如下所示:
var arr:NSArray? = NSArray()

如果将变量定义为非可选项,则无法将其设为nil。您使用的NSArray初始化程序定义为public convenience init?(contentsOfFile path: String) - ?表示它实际上可以返回nil。当您使用!时,您强制解包该值,这会导致值nil时运行时崩溃。

与往常一样,您可以在docs

中阅读更多内容

或者,您可以这样做:

if let tempArr = NSArray(contentsOfFile: plistfinalpath) {
    arr = tempArr
}

通过这种方式,您不需要将arr定义为可选,并且仅在文件内容不为空时才分配给它。

答案 2 :(得分:0)

只需使用以下代码

即可
if let array = NSArray(contentsOfFile: plistfinalpath){
   arr = array
}

在swift中,(!)用于强制解包可选值。 当选项有值时你应该使用它,否则你应该使用上面的代码。