2017-01-19 2 views
3

私は次のコードを使用してUITableViewの細胞を移植しています:このSwiftコードは同等ですか?

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as UITableViewCell! 
    var someString:String 
    cell?.textLabel?.text = someString 
    return cell! 
} 

のXcode:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")! as UITableViewCell 
    var someString:String 
    cell.textLabel?.text = someString 
    return cell 
} 

よりいくつかの周りに遊ぶと、私はこのわずかに異なるコードで同じタスクを実行することができました両方のコードをコンパイルして実行します。迅速な初心者のために、それは選択肢を吸収することが難しかったし、この種の例はちょっと私をもっと混乱させます。誰かがここで何が起こっているのか説明できますか?コードは同等ですか?そして、1つのオプションのスタイルが他よりも望ましいですか?

答えて

4

これらは似ていますが、同じではありません。

asは、オブジェクトを別のオブジェクトとして使用することをコンパイラに知らせるものです。

例では、tableView.dequeueReusableCellは、のいずれかを含むことができるオプションのUITableViewCell?を返します。

Optionalsはどちらかif/letで、いくつかの方法でアンラップすることができます。

if let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") { 
    // cell is a UITableViewCell here, not an optional 
} 
// cell doesn't exist here anymore 

guard

guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") else { 
// cell is nil so it's not even created. We HAVE to exit here 
return 
} 
// cell is a cell is UITableView here, no optional 

を使用したり、安全ではないとされ、それを強制的にクラッシュするアプリケーションを引き起こす可能性があります。バックあなたの質問に今

let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")! 
// cell will be UITableViewCell!, which is an optional that will 
// crash if you try to use it and it's nil 

を(個人的に私は同じくらい私はできる限りこれらを回避し、そして唯一のIBOutletsでそれらを使用)、あなたは定期的なオプションであるUITableViewCell?を、持っています。

最初の例では、最初に!で強制アンラップしてから、UITableViewCellにキャストします。これは実際にはforce-unwrapped-optionalのUITableViewCellになります。これは、アプリがゼロで、使用しようとするとクラッシュすることになります。

2番目の例では、UITableViewCell?UITableViewCell!とすると、同じシナリオになります。

どちらの例でも、cellを使用している場合、?または!を使用する必要があります。これは既に強制解除されているためです。

ただし、force-unwrapped-optionalsを使用しないようにガードを使用することをお勧めします。これは私がカスタムセルを処理する方法である:私はtableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)を使用しています、このメソッドは、オプションを返さないので、あなたは、カスタムクラスを持っていないセルを使用したい場合は

guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as? CustomCell else { 
    fatalError("CustomCell is not in the table view") 
    // Crash with a custom message instead of a generic one 
} 

注意、あなたはこれを使用することができ、アンラッピングについて心配する必要はありません。

2

オプションのアンラッピングとアンラップを強制的に行っています。あなたはそれがすべてで、オプションではありませんかのように、自動的にその値をアンラップするようにコンパイラーに指示します

let x: String! 

として、型の定義するとき あなたは、暗黙的に開封されたとしてオプションを定義します。 別の例は次のようになります。それは、Interface Builderのでインスタンス化されるように、あなたに暗黙的に開封されたoptionalsをアウトレットを定義した場合

@IBOutlet weak var someLabel: UILabel! 

これが一般的です。ただし、このコンセントをInterface Builderに接続するのを忘れた場合は、実行時エラーが発生します。

強制アンラッピングの場合は、任意の値の後に!を追加します。これは、コンパイラがnilかどうかをチェックせずに、コンパイラがそれをアンラップすることを意味します。

暗黙のアンラッピングとは異なり、強制アンラッピングは既存の値に使用されます。つまり、特定の値があると確信しており、まったくゼロを返しません。

IBOutletを除き、一般的には!を使用しないでください。コード全体にif letまたはguard letを使用することができます。あなたが決して知らないので、それは決して無価値を返すことは決してないと思うことはありません!

dequeueReusableCell(withIdentifier:)

このメソッドは、テーブルビュー内の細胞の再利用を扱う:

3

OKがあなたの質問の部分で分割を開始してみましょう。再利用可能なセルがなく、クラスまたはnibファイルを登録していない場合、このメソッドはnilを返します。

let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")! as UITableViewCell 

それではあなたが呼び出すことができます:

cell.textLabel?.text = someString 

を必要としないオプションの値をアンラップにあなたの最初のケースで

、あなたはキャストを作る前に、オプションをアンラップしていますメソッドdequeueReusableCell(withIdentifier:)のセルが返されます。

2番目のケースでは、関数dequeueReusableCell(withIdentifier:)の値を強制的にアンラッピングしていません。

したがって、オプションのチェインを使用してセルを参照するか、強制的にアンラップするオプションのセルを参照する必要があります(オプションの場合は実行時例外を避けることをお勧めします)。

しかし、あなたは、単に呼び出すことすべてを避けることができます。もちろん

let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! UITableViewCell 

を、あなたは(私が意味するカスタムセル用)キャスティングが動作する必要があることを確認する必要があります。だから最終的には、あなたはオプションを持って遊んでいて、asオペレーターを使ってアップキャストとダウンキャストしています。

あなたは、私は強くあなたがUITableView Programming Guider for iOSについて読んお勧めアップキャストの違いについての詳細と

What's the difference between "as?", "as!", and "as"?をダウンキャストを読むことができ、そこから多くのことを学ぶことができます。

私はこれがあなたに役立つことを願っています。

関連する問題