Swift Plist读取和初始化数组作为键的对象

时间:2014-06-13 16:02:12

标签: ios uitableview nsdictionary plist swift

我在Swift中开发了一个基于UITableView的小应用程序。我开始硬编码一些基本数组(包括基本类声明和UITableView出口声明:

import UIKit

class ScenesViewController: UITableViewController {

@IBOutlet var myTableView: UITableView

var sceneName = ["Scene 1", "Scene 2", "Scene 3", "Scene 4", "Scene 5"]
var sceneDetail = ["Hi", "Hello", "Bye", "My Bad", "Happy"]

此代码位于UITableViewController内,其出口全部连接到UITableView。我为此创建了一个名为" Scenes.plist"并试图替换代码。在Objective-C中,我会这样做:

NSString *path = [[NSBundle mainBundle] pathForResource:@"Scenes" ofType:@"plist"];

NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
sceneName = [dict objectForKey:@"SceneName"];
sceneDetail = [dict objectForKey:@"SceneDetail"];

我开始在Swift中这样做:

let path = NSBundle.mainBundle().pathForResource("Scenes", ofType:"plist")

let dict = NSDictionary(contentsOfFile:path)  // Error: 'ScenesViewController.Type' does not have a member named 'path'

我在互联网上寻找解决方案,但却找不到解决方案。所以我采取了下一步行动 - 几乎'单行:

let dict = NSDictionary(contentsOfFile: 
    NSBundle.mainBundle().pathForResource("Scenes", ofType:"plist"))

var sceneName = dict["SceneName"] // Error: 'ScenesViewController.Type' does not have a member named 'dict'

现在,我几乎可以解决的唯一解决方案就是在每一个阵列的一行中拥有所有这些:

var sceneName = NSDictionary(contentsOfFile: 
    NSBundle.mainBundle().pathForResource("Scenes", ofType:"plist").objectForKey("SceneName")
// Warning: Variable 'sceneName' inferred to have type 'AnyObject!', which may be unexpected
// Fix-It: Add an explicit type annotation to silence this warning (var sceneName: AnyObject! = ...)

所以我添加了显式类型注释,以发现存在更多错误。在cellForRowAtIndexPath:函数内:

override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {
    let cell: UITableViewCell = tableView!.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell

    // Configure the cell...

    cell.textLabel.text = sceneName[indexPath!.row] // Error: could not find member 'row'
    return cell
}

实际上有两个错误;我不知道这是否意外重复。下一个错误位于prepareForSegue:sender:方法中:

override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
    if segue?.identifier == "ShowDetails" {
        var detailVC: ScenesDetailViewController = segue!.destinationViewController as ScenesDetailViewController

        var myIndexPath: NSIndexPath = myTableView.indexPathForSelectedRow()

        var row: Int = myIndexPath.row

        detailVC.detailModal = [sceneDetail[row], sceneName[row]] // Error: Could not find an overload for 'subscript' that accepts the supplied arguments
    }
}

同样,有两个错误;但是,我认为这是因为sceneDetailsceneName都被使用了。在Objective-C中,在那些不存在(或者我没有遇到过)的文件中阅读和使用plist似乎存在错误。

提前致谢,

-KodInc

2 个答案:

答案 0 :(得分:19)

要解决您的初始问题,请将代码放在func中,例如:

var memoryName = []
var memoryDetail = []

override func awakeFromNib() {
    super.awakeFromNib()

    let path = NSBundle.mainBundle().pathForResource("Memories", ofType:"plist")
    let dict = NSDictionary(contentsOfFile:path)

    memoryName = dict["MemoryName"] as Array<String>
    memoryDetail = dict["MemoryDetail"] as Array<String>
}

答案 1 :(得分:1)

您可以通过将代码移动到对象初始化后调用的函数来解决此问题。

属性初始化为对象初始化的一部分。您已创建路径和字典作为属性,并尝试使用不符合初始化要求的代码初始化它们。

  

初始化程序无法调用任何实例方法,读取   任何实例属性的值,或将self称为值   直到初始化的第一阶段完成之后。

     

- Swift编程语言 - 初始化 - 安全检查4

此外,您似乎只需要 sceneName sceneDetail 作为属性,因此您可以在用于填充sceneDetail的方法范围内完全移动它们和初始化后的sceneName。

我很难说下标错误完全因为我不知道具体的数据类型VC.detailModal应包含什么类型;即便如此,似乎错误的对象类型被传递到detailModal数组中。对此问题的一个很好的描述是Swift and arrays