每当我的视图通过以下方法加载时,我就是在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中所做的工作呢?
答案 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中,(!)用于强制解包可选值。 当选项有值时你应该使用它,否则你应该使用上面的代码。