2017年6月21日水曜日

Swift エラーメッセージ - 型変換(Type Casting)

Cannot downcast from 'UIView' to a more optional type 'UITableViewHeaderFooterView?'
  • エラーが発生するコード
     if let headerView = view as! UITableViewHeaderFooterView {
       ...
     }
  • 原因:viewがOptionalでないため、UITableViewHeaderFooterViewとして扱えない。
  • 修正
    let headerView = view as! UITableViewHeaderFooterView
    ...

Initializer for conditional binding must have Optional type, not 'UITableViewCell'
  • エラーが発生するコード
    if let cell = sender as! UITableViewCell {
       ....
    }
  • 原因:senderがOptionalなのでUITableViewCellとして扱えない。
  • 修正
    if let cell = sender as! UITableViewCell? {
        ....
    }
Cannot convert value of type 'Any?' to expected argument type 'UITableViewCell'
  • エラーが発生するコード
    if let indexPath = self.tableView.indexPath(for: sender) {
        ...
    }
  • 原因:senderの型がAny?なのでキャストが必要。
  • 修正
    if let indexPath = self.tableView.indexPath(for: sender as! UITableViewCell) {
        ...
    }



2017年6月18日日曜日

swift エラーメッセージ


メッセージ:Editor placeholder in source file
Xcodeの自動修正でコードを置き換えた場合に、適切な値に置き換えるべきplaceholderがセットされることがある。
これをそのままにしてビルドした場合に発生する。

例: 
self.navigationController!.setNavigationBarHidden(true, animated: Bool)

Boolがplaceholder。次のように修正する。
self.navigationController!.setNavigationBarHidden(true, animated: true)



メッセージ:Result of call to 'someFunc()' is unused" 
someFuncの戻り値を変数にセットしてが、それを使用しない場合に発生する警告。

例:
let val = someFunc()

valを使用しない場合に発生する。次のように変更する
let _ = someFunc()


メッセージ:Cannot use mutating member on immutable value: '...' is a 'let' constant
パラメータの変数はletで宣言されたConstant扱いなので代入不可のため発生する警告。

例:
func someFunc(someParam: SomeType) {
    someParam = someObj
}
letかvarで別の変数に代入して使用する。代入後に値を変更するかどうかでlet, varを使い分ける。名前は同じでも良いが、別オブジェクトになる。
func someFunc(someParam: SomeType) {
    var someParam = someObj
}

呼び出し元の値を変更したい場合は新規オブジェクトをreturnし、呼び出し元でオブジェクトを入れ替える。
func someFunc(someParam: SomeType) {
    var newParam = someObj
    ....
    return newParam
}

呼び出し元にあるオブジェクト (ArrayやDictionanayなど)を置換せず、そのプロパティーや要素の一部を変更したいような場合はsomeParamをinoutで宣言する。
varで宣言されていれば、someParamそのものの置換も可能。
func someFunc(someParaminout SomeType) {
    someParam.someProp = someVal
}

この場合は、呼び出し側を次のようにする。
someFunc(&someObj)



メッセージ:Unknown class SomeClass in Interface Builder file.
IBで設定したクラスが見つからない場合に発生する。
ソースコードでクラスを追加してからIBでインスタンスにそのクラウを設定していれば、このエラーは発生しない。原因は様々と思われるが、次の場合が含まれる。
  • IBで設定した後で、ソースコードでクラス名を変更した。
  • 他のプロジェクトからIBで部品のコピー/ペーストを行った。
当該の部品をIBで選択、インスペクターでクラス設定をチェックする。
前者の場合は変更前のクラス名のままになっているので、プルダウンで新しい名前のものに変更する。
後者の場合はそのクラス名しか表示されない。プルダウンで変更できないので、一旦手入力でスーパークラスの名前に書き換える。その後プルダウンを開くとそのサブクラスの一覧が表示されるので、適切なものに設定する。