ワーニングはエラーだ
今更かも知れませんがワーニングはエラーです。ワーニングはエラーです。ワーニングはエラーなんです。ワーニングを放置してコミットする意味がわかりません。なのでワーニングを修正していきます。
このエントリは前回のエントリの続きです。
ワーニングたち
Variable 'nantoka' was never mutated; consider changing to 'let' constant
これは非常にいいワーニングですね。varだけど一度しか代入されていないものはletじゃねえの?っていういいおせっかいです。Fix-itがあるのでクリックしちゃいましょう。たぶん賢いSwiftコンパイラのことなのでletだろうがvarだろうが変化するかしないかをきちんと解析して最適化をかけてくれると思うので、仕上がりのバイナリにそれほど違いは出ないと思うのですが、letにしておけばSwiftコンパイラは安心して定数としての最適化をかけることができます。
それにもましてconstを増やせば増やすほどコードは頑丈になります。letしましょう。
Forced cast of '[UIWindow]' to same type has no effect
let windows = UIApplication.sharedApplication().windows as! [UIWindow]
こういうの、返り値の方がちゃんと直っているみたいです。昔はNSなんとかが返っていたんでしょう。素直にFix-itで消しちゃいましょう。
今気づいたんですが、左っ側のワーニングとエラーの一覧のペインのエントリをクリックするとその場所にジャンプするだけじゃなくてFix-itが使えるときはFix-itの内容を表示してエンターするだけで治るようになってますね。たくさん修正するときにクリックエンターの繰り返しで簡単にできるようになっていてとてもよいです。一気に直すみたいなのもあるといいなと思いましたが、一個一個一応見ようぜというAppleの心遣いなんでしょうか。
Treating a forced downcast to '[String: AnyObject]' as optional will never produce 'nil'
let titleDict: NSDictionary = [NSForegroundColorAttributeName: colorPalette.uiColorText] UINavigationBar.appearance().titleTextAttributes = titleDict as! [String : AnyObject]
これ実は前回のエントリでas!に直したものだと思います。これ、NSDictionaryを普通の辞書に直しているからおかしなことになっているので、NSDictionaryを普通の辞書に直します。
let titleDict: [String : AnyObject] = [NSForegroundColorAttributeName: colorPalette.uiColorText] UINavigationBar.appearance().titleTextAttributes = titleDict
こうですね。変なボクシングとアンボクシングが必要になりました。Swit2.2たしかに前よりいいね。
Use of string literal for Objective-C selector is deprecated; use '#selector' instead
SegmentTableCell(tableView: self.tableView, id: "blackPlayerSegment", labelText: "Black player", segmentItems: ["Human", "Computer"], selectedSegmentIndex: blackSSI, targetObject: self, targetSelector: "changeSegmentBlackPlayer:"),
こういうやつです。ここでtargetSelector: "changeSegmentBlackPlayer:"
がだめらしい。この"changeSegmentBlackPlayer:"
Objective-Cのメッセージパッシング原理主義的オブジェクト指向では許されていたやつですね。当然コンパイル時に全くチェックができないのでここをコンパイラがチェックできる形式にする…ということかな? ここで不正なセレクタを指定すると
となります。だめみたいですね。
'++' is deprecated; it will be removed in Swift 3
インクリメント演算子はなくなると。残念です。a += 1
みたいに書けということらしいです。なんの利点があるんでしょうか。とはいえ私はインクリメント演算子はあんまり好きじゃないです。というのもa += 1
と書いたほうが代入文だということがわかりやすいからです。そりゃそうだろ、と言われるかもしれませんが、そりゃそうです。「インクリメント演算子の便利さはfor文とか関数の引数としてとかあんだろ」と言われるかもしれません。例えばCで例を出すと
/* C */
q = f(i++);
みたいな感じで一行にまとめられます。便利ですね。でも
/* C */
q = f(i++) + g(++i);
ってどうなんでしょう。これはおんなじSequence point内でiに対する変更と読み取りが両方発生するのでコンパイラワーニングになります。でもってその結果はコンパイラの作者次第です。てことはおんなじ行内でこういうことできないんだから明示的にした方がいいよねってなるとa += 1
として独立した行に書くのがいいのかもしれません。当然(a+=1)
として置き換えてその場でインクリメントしてそのまま使うこともできますが、流石にそんな気持ち悪いのは書かねえだろってこと・・・でしょうか。
/* C */ q = f(i) + g(i+=1); i+=1;
やっぱちょっときもいですもんね。
さらに、Swiftは演算子オーバーロードがあるので
var q = f(i++) + g(++j)
これは大丈夫でしょうか。このコードだけではわかりません。やっぱりSequence pointを大事にする姿勢からするとインクリメント演算子はとりあえずなくしてきれいに書く癖を強制させる方向性なのかな、ということをインクリメント演算子の将来的な削除から考えました。結論:どっちでもいい!
メイヤー先生はいらないと考えているみたいですね。

オブジェクト指向入門 第2版 原則・コンセプト (IT Architect’Archive クラシックモダン・コンピューティング)
- 作者: バートランド・メイヤー,酒匂寛
- 出版社/メーカー: 翔泳社
- 発売日: 2007/01/10
- メディア: 単行本(ソフトカバー)
- 購入: 11人 クリック: 307回
- この商品を含むブログ (130件) を見る
C style for statement is deprecated and will be removed in a future version of Swift
for var by : CGFloat = 0; by <= width; by += piece_width { ...
って感じのやつです。Pythonみたいに書くのがいいというわけですね。つまり
for i in 0..<5 { }
みたいな書き方ですね。ただこれ、増分1固定なので僕のオリジナルの文は書き直せません。ここでstrideを使います。
for i in stride(from: 0, through: width: by: piece_width) { }
とすると上と同じになります。
stride(from: 0, to: 1, by: 0.2) // 0.0, 0.2, 0.4, 0.6, 0.8 stride(from: 0, through: 1, by: 0.2) // 0.0, 0.2, 0.4, 0.6, 0.8, 1.0
という違いがあります。ここにはStrideableなる新しい型の作用があるみたいですね。参考:
Swift: Six Killer Features — Erica Sadun
swift-evolution/0007-remove-c-style-for-loops.md at master · apple/swift-evolution · GitHub
Immutable value 'nantoka' was never used; consider replacing with '_' or removing it
これは使われてない変数の取り扱いに関する警告ですね。消せるところは消しちゃいましょう。forの条件に使われていたりする場合は_
に置き換えちゃいましょう。
for _ in 0..<height { var row: [Double] = [] for _ in 0..<width { row += [initVal] } self.zones += [row] }
ちなみにこうやっても上と下の_は混じりませんよ。安心してください。
'var' parameters are deprecated and will be removed in Swift 3
func sum (var array : [Int]) {
これ、変数は基本constで、変更する場合はvarをつけなければいけませんでした。これはそのうちinout
に置き換わる予定です。こうやってimmutablityを重視するのって本当にいいですね。
Result of call to non-mutating function 'sort' is unused; use 'sortInPlace' to mutate in-place
これはワーニングの中でも特に重要に思います。以前はsort関数はsequenceの中身を直接変更するものでしたが、これからはそのsortしたものを返す関数になっているようです。
arr.sort({ $0.0 > $1.0 })
とかやると何にもしない文になります。sortInPlaceしましょう、というよりarr = art.sort~
と書き直したほうが良いように思います。RValue optimizationがかかる…のかな?そうだといいな。
プロジェクトの設定のワーニング
こんな感じのものが出ました。
面倒なんでPerform Changesしちゃいましょう。
一応調べてみると
- Turn on "Enable Testability" When Debugging
この"Enable Testability"はテストクラスの冒頭で
@testable import ClassToBeTested
するだけで大丈夫になるみたいです。便利ですね。
- Disable Safety
これは-Ounchecked
フラグの代わりみたいです。私のような完璧無敵超人に配列の境界チェックは必要ないのでuncheckedにしているのですが、Disable Safetyで置き換えみたいです。
綺麗になりました
ワーニングは全部修正できたみたいです。というわけで、次はSwift1.2と2.2で私の書いたオセロのプログラムを使ってスピードの比較でも暇な時にやってみたいと思います。