私は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」と呼ばれるこのための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'
さて、私がほとんど頼ることができる唯一の解決策は、配列ごとに1行にすべてを配置することです。
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
}
実際には2つのエラー;これが誤って複製されているかどうかはわかりません。次のエラーは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
}
}
ここでも、2つのエラーがあります。ただし、これはsceneDetail
とsceneName
の両方が使用されているためだと思います。 Objective-Cにない(または私が遭遇していない)ファイルのplistを読んだり使用したりすると、いたるところにエラーがあるようです。
最初の問題を解決するには、次のような関数内にコードを配置します。
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>
}
これを解決するには、オブジェクトの初期化後に呼び出される関数にコードを移動します。
プロパティは、オブジェクトの初期化の一部として初期化されます。パスとdictをプロパティとして作成し、初期化の要件を満たさないコードでそれらを初期化しようとしています。
初期化子は、初期化の最初のフェーズが完了するまで、インスタンスメソッドを呼び出したり、インスタンスプロパティの値を読み取ったり、selfを値として参照したりすることはできません。
-Swiftプログラミング言語-初期化-安全性チェック4
また、sceneNameとsceneDetailだけが必要なようですプロパティ。初期化後にsceneDetailとsceneNameを設定するために使用するメソッドのスコープ内で完全に移動できます。
添え字エラーが何であるか正確にを言うのは難しいです。なぜなら、どのタイプのデータdetailVC.detailModalが含まれるべきかわからないからです。それでも、間違ったタイプのオブジェクトがdetailModal配列に渡されているようです。この問題のちょっとした説明は Swift and array