Objective-C 从 .plist 中检索的样式在 Swift 中不起作用?
Objective-C style retrieving from .plist not working in Swift?
每当我的视图通过以下方法加载时,我都在 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)!
中的值,所以数组为空并且因为我正在解包它,它显示错误.那么我怎样才能实现我在 objective C 中所做的事情呢?
只需将 arr
变量定义为可选变量,如下所示:
var arr:NSArray? = NSArray()
当一个变量被定义为非可选时,你不能使它成为nil
。您使用的 NSArray
初始值设定项被定义为 public convenience init?(contentsOfFile path: String)
- ?
意味着,它实际上可以 return a nil
。当您使用 !
时,您强制解包该值,当值为 nil
.
时会导致运行时崩溃
与往常一样,您可以在 docs
中阅读更多内容
或者,您可以这样做:
if let tempArr = NSArray(contentsOfFile: plistfinalpath) {
arr = tempArr
}
这样,您不需要将 arr
定义为可选的,并且只会在文件内容不为空时分配给它。
完整的答案涉及理解 "optional" 的概念。
什么是可选的?
在 Swift 中,您可以在类型后附加 ?
将变量声明为可选。当您这样做时,这意味着该变量可以保存一个值或根本不保存。当您将变量声明为非可选变量时,编译器会确保它始终保存一个值。
- 声明一个变量为可选:
var myOptionalVariable: NSArray?
- 将变量声明为非可选变量:
var myVariable = NSArray()
注意在非可选变量中,编译器强制我们给它一个值(在本例中只是一个空数组)。这是因为编译器允许当一个变量不是可选的时,它在每时每刻都有一个值。 注意区别:第一个语句只是声明变量作为可选NSArray,第二个语句初始化并分配一个新的空NSArray给变量。
为什么可选的有用?
随着可选值的引入,我们对变量中包含的数据的存在有了编译时安全性。当不使用可选变量时,我们肯定知道变量始终保持一个值。同时,当使用可选变量时,我们不得不处理值可能不存在的情况,而不是默默地处理它(这就是 [=79= 中的 nil
发生的情况]).从可选中提取值称为 unwrapping
解包可选(即从可选中提取值)
要"extract" 可选变量的值,您需要将其解包。有几种方法可以解包一个可选变量,假设 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
永远不会为 nil”这在你的情况下是不正确的,它会导致崩溃并出现错误 Fatal error: unexpectedly found nil while unwrapping an Optional values
。您应该始终避免强制解包,除非您真的非常确定您的数据。
长话短说
您有 2 个可行的解决方案:
- 不要使用强制解包(参见上面关于解包的选项)
- 将您的变量
arr
转换为可选变量(通过以这种方式声明它:var arr: NSArray?
),然后在您使用它时处理(非强制)展开(即在您的 tableView 中)数据源方法)
哪一个更适合你的情况,取决于 arr
的意思,如果它是可选的有意义,那就去做吧,否则,就让它不可选并分配一些默认值。
只需使用以下代码,
if let array = NSArray(contentsOfFile: plistfinalpath){
arr = array
}
在swift中,(!)用于强制解包可选值。
当可选值有值时,你应该使用它,否则你应该使用上面的代码。
每当我的视图通过以下方法加载时,我都在 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)!
中的值,所以数组为空并且因为我正在解包它,它显示错误.那么我怎样才能实现我在 objective C 中所做的事情呢?
只需将 arr
变量定义为可选变量,如下所示:
var arr:NSArray? = NSArray()
当一个变量被定义为非可选时,你不能使它成为nil
。您使用的 NSArray
初始值设定项被定义为 public convenience init?(contentsOfFile path: String)
- ?
意味着,它实际上可以 return a nil
。当您使用 !
时,您强制解包该值,当值为 nil
.
与往常一样,您可以在 docs
中阅读更多内容或者,您可以这样做:
if let tempArr = NSArray(contentsOfFile: plistfinalpath) {
arr = tempArr
}
这样,您不需要将 arr
定义为可选的,并且只会在文件内容不为空时分配给它。
完整的答案涉及理解 "optional" 的概念。
什么是可选的?
在 Swift 中,您可以在类型后附加 ?
将变量声明为可选。当您这样做时,这意味着该变量可以保存一个值或根本不保存。当您将变量声明为非可选变量时,编译器会确保它始终保存一个值。
- 声明一个变量为可选:
var myOptionalVariable: NSArray?
- 将变量声明为非可选变量:
var myVariable = NSArray()
注意在非可选变量中,编译器强制我们给它一个值(在本例中只是一个空数组)。这是因为编译器允许当一个变量不是可选的时,它在每时每刻都有一个值。 注意区别:第一个语句只是声明变量作为可选NSArray,第二个语句初始化并分配一个新的空NSArray给变量。
为什么可选的有用?
随着可选值的引入,我们对变量中包含的数据的存在有了编译时安全性。当不使用可选变量时,我们肯定知道变量始终保持一个值。同时,当使用可选变量时,我们不得不处理值可能不存在的情况,而不是默默地处理它(这就是 [=79= 中的 nil
发生的情况]).从可选中提取值称为 unwrapping
解包可选(即从可选中提取值)
要"extract" 可选变量的值,您需要将其解包。有几种方法可以解包一个可选变量,假设 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
永远不会为 nil”这在你的情况下是不正确的,它会导致崩溃并出现错误 Fatal error: unexpectedly found nil while unwrapping an Optional values
。您应该始终避免强制解包,除非您真的非常确定您的数据。
长话短说
您有 2 个可行的解决方案:
- 不要使用强制解包(参见上面关于解包的选项)
- 将您的变量
arr
转换为可选变量(通过以这种方式声明它:var arr: NSArray?
),然后在您使用它时处理(非强制)展开(即在您的 tableView 中)数据源方法)
哪一个更适合你的情况,取决于 arr
的意思,如果它是可选的有意义,那就去做吧,否则,就让它不可选并分配一些默认值。
只需使用以下代码,
if let array = NSArray(contentsOfFile: plistfinalpath){
arr = array
}
在swift中,(!)用于强制解包可选值。 当可选值有值时,你应该使用它,否则你应该使用上面的代码。