web-dev-qa-db-ja.com

なぜSwift UITableViewControllerテンプレートはtableView cellForRowAtIndexPathメソッドでオプション引数を使用しますか?

新しいUITableViewControllerクラスを作成すると、コメント化されたオーバーライドメソッドが表示されます。

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

    // Configure the cell...

    return cell
}
*/

メソッドのコメントを解除できますが、エラーのため機能しません

'UITableView?' does not have a member named 'dequeueReusableCellWithIdentifier'

その理由は、tableViewがオプションのタイプ "ITableView?"として定義されており、メソッドを呼び出す前にtableViewをアンラップする必要があるためです。たとえば、次のようなものです。

let cell = tableView!.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)

しかし、それらを暗黙的にラップされていないオプションにし、なしでtableViewを使用することができます

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

質問は:なぜXcodeはそれらをオプションとして定義するのですか?暗黙的にラップされていないオプションに対して、何らかの理由や利点がありますか?このメソッドが常に非nill値を取得することを確認できますか?

また、別のエラーが発生します

Constant 'cell' inferred to have type 'AnyObject!', which may be unexpected
Type 'AnyObject!' cannot be implicitly downcast to 'UITableViewCell'; did you mean to use 'as' to force downcast?

次のように最後にUITableViewCellとして追加することで修正できます。

let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell

デフォルトでテンプレートが次のようにならない理由はわかりません。

/*
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
    let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell //or your custom class

    // Configure the cell...

    return cell
}
*/
25
John Kakon

はい、それは奇妙です。実際、テンプレートが提供するメソッドを消去し、それぞれの入力を開始すると、Xcodeのオートコンプリートは、暗黙的にラップされていないオプション引数などのメソッドを提案します

tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!

テンプレートは現在間違っており、手で入力するときにテンプレートのバージョンが提案されていないという事実を考えると、後で修正される可能性があると思います。ただし、それらをそのままにしておくと、通常どおり呼び出され、必要に応じてパラメーターを正しくアンラップする限り機能します。

議論の詳細については this question をご覧ください。

17
Cezar

実際、これはデリゲートメソッドを使用する正しい方法です。

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("CELL_ID", forIndexPath: indexPath)
    cell.textLabel.text = "aaaa"
    return cell

}
22
Ryan