Ios 从中检索Objective-C样式。plist不在Swift中工作?

Ios 从中检索Objective-C样式。plist不在Swift中工作?,ios,objective-c,swift,plist,Ios,Objective C,Swift,Plist,每当通过以下方法加载视图时,我都在Objective-C中的.plist中检索数据- @interface ListTableViewController () @end @implementation ListTableViewController NSArray *dict; -(void)viewDidAppear:(BOOL)animated { NSString *arr= [NSSearchPathForDirectoriesInDomains(NSDocumentDi

每当通过以下方法加载视图时,我都在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];

}
现在,对于斯威夫特,我正在做同样的事情-

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()
  }
}

但是因为我必须打开行
arr=NSArray(contentsOfFile:plistfinalpath)中的值当plist为空时当应用程序第一次启动时,数组为空,并且由于我正在展开它,因此显示错误。那么,我如何实现我在目标C中所做的呢?

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

当变量定义为非可选时,不能将其设为
nil
。您使用的
NSArray
初始值设定项被定义为
公共便利init?(contentsOfFile path:String)
意味着它实际上可以返回一个
nil
。当您使用
nil
时,强制展开该值会导致运行时崩溃

和往常一样,你可以在书中读到更多


或者,您可以执行以下操作:

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

这样,您就不需要将
arr
定义为可选变量,只在文件内容不为空时才分配给它。

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

当变量定义为非可选时,不能将其设为
nil
。您使用的
NSArray
初始值设定项被定义为
公共便利init?(contentsOfFile path:String)
意味着它实际上可以返回一个
nil
。当您使用
nil
时,强制展开该值会导致运行时崩溃

和往常一样,你可以在书中读到更多


或者,您可以执行以下操作:

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

这样,您就不需要将您的
arr
定义为可选,而只在文件内容不为空时才将其分配给它。

完整的答案包括理解“可选”的概念

什么是可选的? 在Swift中,您可以将变量声明为可选变量,并在类型后附加
。当您这样做时,这意味着变量可以保存值,也可以根本不保存值。当您将变量声明为非可选变量时,编译器将确保它始终保持一个值

  • 将变量声明为可选:
    var myOptionalVariable:NSArray?
  • 将变量声明为非可选:
    var myVariable=NSArray()
请注意,在非可选变量中,编译器强制我们给它一个值(在本例中,它只是一个空数组)。这是因为编译器允许当变量不是可选变量时,它在每一时刻都保存一个值注意区别:第一条语句只是将变量声明为可选NSArray,第二条语句初始化并为变量分配一个新的空NSArray

为什么可选是有用的? 随着optionals的引入,我们对变量中包含的数据的存在有了编译时安全性。当不使用可选变量时,我们可以确定变量始终保持一个值。同时,当使用一个可选变量时,我们不得不处理一个值可能不存在的情况,而不是静默地处理它(这就是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
永远不会为零”,在您的情况下,这是不正确的,它会导致崩溃,错误为
致命错误:在展开可选值时意外发现为零。除非您对数据非常确定,否则应始终避免强制展开

长话短说 您有两个可行的解决方案:

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

哪一个更适合您的情况,取决于arr的含义,如果可选是有意义的,那么就选择它,否则,只需将其保留为非可选并指定一些默认值。

完整的答案包括理解“可选”的概念

什么是可选的? 在Swift中,您可以将变量声明为可选变量,并在类型后附加
。当您这样做时,这意味着变量可以保存值,也可以根本不保存值。当您将变量声明为非可选变量时,编译器将确保它始终保持一个值

  • 将变量声明为可选:
    var myOptionalVariable:NSArray?
  • 将变量声明为非可选:
    var myVariable=NSArray()
请注意,在非可选变量中,编译器强制我们给它一个值(在本例中,它只是一个空数组)。这是因为编译器允许当变量不是可选变量时,它在每一时刻都保存一个值注意区别:第一条语句只是将变量声明为可选NSArray,第二条语句初始化并为变量分配一个新的空NSArray

为什么可选是有用的? 随着介绍