Beta4がリリースされたので、変更点をいくつかピックアップしました。
待望のアクセスコントロールができるようになった
public
, internal
, private
のスコープでアクセスコントロールできるようになりました。
アクセス修飾子 | 説明 |
---|---|
public | 定義されているターゲット外からもアクセスすることができる |
internal | 定義されているターゲット内からアクセスすることができる |
private | 定義されているソースファイル内からアクセスすることができる |
記載を処略した場合はinternal
がデフォルトで適用されます。
// An example class in a framework target.
public class ListItem: NSObject {
public var text: String
public var isComplete: Bool
// Readable throughout the module, but only writeable from
// within this file.
private(set) var UUID: NSUUID
public init(text: String, completed: Bool, UUID: NSUUID) {
self.text = text
self.isComplete = completed
self.UUID = UUID
}
func refreshIdentity() {
self.UUID = NSUUID()
}
// Must be public because it overrides a public method and is
itself
// part of a public type.
public override func isEqual(object: AnyObject?) -> Bool {
if let item = object as? ListItem {
return self.UUID == item.UUID
}
return false
}
}
参考 Xcode Release Notes
Swift Enables Access Control
Swift access control has three access levels:
• private entities can only be accessed from within the source file where they are defined.
• internal entities can be accessed anywhere within the target where they are defined.
• public entities can be accessed from anywhere within the target and from any other context
that imports the current target’s module.
@IBOutletのプロパティ定義はオプショナルが必須になった
@IBOutletのプロパティが軒並みエラーになります。
↓
お二人方からコメントでご指摘を頂いたので追記致します。ありがとうございます。m(_ _)m @7/22 16:00
[ 追記 ここから ]
以下のようなコンパイルエラーが表示されます。
エラーメッセージ
IBOutlet' property has non-optional type 'UILabel'
解決方法は2通りあります。
1.オプショナルを明記する Optionals(?)
2.暗黙的アンラップオプショナルを明記する Implicitly Unwrapped Optionals(!)
ストーリボードからドラッグ&ドロップで@IBOutlet
を作成すると以下のようになるので、2.の方が推奨されているようです。
また、ビューはaddSubview
されている場合、参照は親のビューが保持(strong)しているので、ここでの参照はweakが適切です。
暗黙的アンラップオプショナルは以下ような場面の利用が想定されます。
タイミング的にnilの時があるけど参照時には値がセットされていることが自明なとき
self.nameLabel.removeFromSuperview()
で、参照を破棄すると
self.nameLabel.text = "Hoge Fuga"
でEXEC_BAD_INSTRUCTION
になるので気をつける必要があります。
[ 追記 ここまで ]
さらにコメントを頂いたので追記致します。ありがとうございます。m(_ _)m @7/23 10:30
[ 追記 その2 ここから ]
AppleのSwiftドキュメントでは以下の記載があります。
暗黙的アンラップオプショナルにすべき(推奨)
Using Swift with Cocoa and Objective-C
When you declare an outlet in Swift, you should make the type of the outlet an implicitly unwrapped optional.
とはいえ、このOutlet
のプロパティはnilになる可能性(※)があるので、プロパティにアクセスする場合はオプショナルを明示して利用しようかと考えています。
※ nilになる可能性
- Storyboardからコネクションが正しく張れていない
- 参照を保持している親ビューが開放された
- プロパティのビュー自身が
removeFromSuperview
した - プロパティに明示的にnilを代入した
- など
Outlet
のオプショナルをより堅牢に記述するには、についてコメント欄にて議論されています。
是非合わせてご参照ください。
補足
Beta3からBeta4でドキュメントも変更されています。
Beta3までは、Outlet
のプロパティはコンパイラが自動的に暗黙的アンラップオプショナルに変更していたようです。
When you declare an outlet in Swift, the compiler automatically converts the type to a weak implicitly unwrapped optional and assigns it an initial value of nil.
参照
[ 追記 その2 ここまで ]
以下記述は取り消しました。
[ 取り消し ここから ]
オプショナルな設定にしてあげます
↓
@IBOutlet
なプロパティを利用しているところは、値(参照)がセットされていると思うのでアンラップにしました。
オプショナルバインディングで記述するほうがより丁寧なのかもしれません
[ 取り消し ここまで ]
参考 Xcode Release Notes
Known issues in Xcode 6 beta 4
Swift
• You cannot conditionally assign to a property of an optional object. (16922562)
配列の要素の型指定の記法はBeta3以上の記法が必須になった
以下はBeta2までの記法で、Beta3から記法が変わりましたがエラーにはならずワーニングでしたが、Beta4からは必須になりました。
↓
UIntができてIntとUIntを明示的な使い分けが必要になった
NSUInteger
型に対応するUInt
型はBeta3までなかったので、ObjCと連携するときはNSUInteger
型はInt
型を利用していました。Beta4からUInt
型ができたので、NSUInteger
型のところはUInt
型に書き直す必要があります。
例えば以下のようなデリゲートでNSUInteger
型を指定している場合
@protocol ViewPagerDataSource <NSObject>
- (NSUInteger)numberOfTabsForViewPager:(ViewPagerController *)viewPager;
- (UIView *)viewPager:(ViewPagerController *)viewPager viewForTabAtIndex:(NSUInteger)index;
end
↓
SwiftではUInt
型で記述します。
func numberOfTabsForViewPager(viewPager: ViewPagerController) -> UInt {
...
}
func viewPager(viewPager: ViewPagerController, viewForTabAtIndex index: UInt) -> UIView {
...
}
// => OK
ちなみにNSUInteger
型はSwiftでは使えません。
func numberOfTabsForViewPager(viewPager: ViewPagerController) -> NSUInteger {
...
}
func viewPager(viewPager: ViewPagerController, viewForTabAtIndex index: NSUInteger) -> UIView {
...
}
// => ERROR Use of undeclared type 'NSUInteger'; did you mean to use 'Int'?
ランドマークアノテーションをサポート
以下の記法が利用できるようになりました。Xcodeのジャンプバーから対象に
//MARK:
//TODO:
//FIXME
例
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: UITableViewDelegate
override func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
...
}
参考 Xcode Release Notes
Landmarks
Xcode now supports //MARK:, //TODO: and //FIXME landmarks to annotate your code and
lists them in the jump bar. (14768427)
StoryboardでUIScrollView系(UITableViewなど)を利用すると出るワーニングが消えた
StoryboardでAutoLayoutを使用時にUIScrollView系を利用すると、コンストレイントのワーニングが常に出ており取り除くこともできなかったのですが、このワーニングがでなくなりました。
Beta3まで以下のようなワーニングが出ていました。
感想
UIntのIntの使い分けはコンバージョンの記述が増え、IBOutletのオプショナルもアンラップの記述が増えるのでちょっと残念です。
アクセスコントロールはみんなが待望していたのでありがたいですね。ライブラリ配布の懸念もひとつ解消されました。