Xcode6 Beta4 でアクセス修飾子がきた！

Beta4がリリースされたので、変更点をいくつかピックアップしました。

## 待望のアクセスコントロールができるようになった

`public`, `internal`, `private`のスコープでアクセスコントロールできるようになりました。

|アクセス修飾子|説明|
|:-----|:-----|
|public|定義されているターゲット外からもアクセスすることができる|
|internal|定義されているターゲット内からアクセスすることができる|
|private|定義されているソースファイル内からアクセスすることができる|

記載を処略した場合は`internal`がデフォルトで適用されます。

```Swift
// 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のプロパティが軒並みエラーになります。

![WTDCommentCell_swift.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/5f333e2d-298c-6802-2d9a-7815d0fd491a.jpeg "WTDCommentCell_swift.jpg")


↓


### お二人方からコメントでご指摘を頂いたので追記致します。ありがとうございます。m(_ _)m　@7/22 16:00


[ 追記 ここから ]

以下のようなコンパイルエラーが表示されます。

![WTDCommentCell_swift.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/ee1a1d27-1713-3cf7-4cb1-539ef8195f0e.jpeg "WTDCommentCell_swift.jpg")


エラーメッセージ

```Swift
IBOutlet' property has non-optional type 'UILabel'
```	


解決方法は２通りあります。

１．オプショナルを明記する Optionals(?)
２．暗黙的アンラップオプショナルを明記する Implicitly Unwrapped Optionals(!)

ストーリボードからドラッグ＆ドロップで`@IBOutlet`を作成すると以下のようになるので、２.の方が推奨されているようです。
また、ビューは`addSubview`されている場合、参照は親のビューが保持(strong)しているので、ここでの参照はweakが適切です。

![WTDCommentCell_swift.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/df2d88c3-1e60-543e-7b55-61ea9434a38b.jpeg "WTDCommentCell_swift.jpg")


暗黙的アンラップオプショナルは以下ような場面の利用が想定されます。

>タイミング的にnilの時があるけど参照時には値がセットされていることが自明なとき

```Swift
self.nameLabel.removeFromSuperview()
```

で、参照を破棄すると

```Swift
self.nameLabel.text = "Hoge Fuga"
```

で`EXEC_BAD_INSTRUCTION`になるので気をつける必要があります。


[ 追記 ここまで ]

### さらにコメントを頂いたので追記致します。ありがとうございます。m(_ _)m　@7/23 10:30

[ 追記 その２ ここから ]


AppleのSwiftドキュメントでは以下の記載があります。

>暗黙的アンラップオプショナルにすべき（推奨）

[Using Swift with Cocoa and Objective-C](https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/BuildingCocoaApps/WritingSwiftClassesWithObjective-CBehavior.html)

>When you declare an outlet in Swift, you should make the type of the outlet an implicitly unwrapped optional.

![Using_Swift_with_Cocoa_and_Objective-C__Writing_Swift_Classes_with_Objective-C_Behavior.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/0a07c899-ccc0-e9a3-7639-2794d4bfccb6.jpeg)


とはいえ、この`Outlet`のプロパティはnilになる可能性（※）があるので、プロパティにアクセスする場合はオプショナルを明示して利用しようかと考えています。

![WTDCommentCell_swift.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/5b52217b-1a6f-8408-de61-b93b4710094b.jpeg)


#### ※ 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.

参照

[Swiftでの@IBOutletの振る舞い](http://blog.morizotter.com/2014/06/15/swift-iboutlet/)

[ 追記 その２ ここまで ]

### 以下記述は取り消しました。

[ 取り消し ここから ]

~~オプショナルな設定にしてあげます~~

![WTDCommentCell_swift.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/c6e82631-35de-ec72-bf90-c4d1cce09e44.jpeg "WTDCommentCell_swift.jpg")

↓

~~`@IBOutlet`なプロパティを利用しているところは、値（参照）がセットされていると思うのでアンラップにしました。
オプショナルバインディングで記述するほうがより丁寧なのかもしれません~~

![WTDCommentCell_swift.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/20a8f997-9bb1-5362-62d7-6a3201f9f2fa.jpeg "WTDCommentCell_swift.jpg")


[ 取り消し ここまで ]


### 参考 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からは必須になりました。

![Edges_swift.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/0e5fe476-c254-c960-4c33-6e5cc1c02ce6.jpeg "Edges_swift.jpg")


↓


![Edges_swift.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/4c2842b1-5f5e-f3ac-33ff-fdb2631ae73e.jpeg "Edges_swift.jpg")


## UIntができてIntとUIntを明示的な使い分けが必要になった

`NSUInteger`型に対応する`UInt`型はBeta3までなかったので、ObjCと連携するときは`NSUInteger`型は`Int`型を利用していました。Beta4から`UInt`型ができたので、`NSUInteger`型のところは`UInt`型に書き直す必要があります。

例えば以下のようなデリゲートで`NSUInteger`型を指定している場合

```ObjC
@protocol ViewPagerDataSource <NSObject>
- (NSUInteger)numberOfTabsForViewPager:(ViewPagerController *)viewPager;
- (UIView *)viewPager:(ViewPagerController *)viewPager viewForTabAtIndex:(NSUInteger)index;
end
```

↓

Swiftでは`UInt`型で記述します。

```Swift
func numberOfTabsForViewPager(viewPager: ViewPagerController) -> UInt {
  ...
}
    
func viewPager(viewPager: ViewPagerController, viewForTabAtIndex index: UInt) -> UIView {
  ...
}
// => OK
```


ちなみに`NSUInteger`型はSwiftでは使えません。

```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のジャンプバーから対象に

```Swift
//MARK:
//TODO:
//FIXME
```

例


```Swift
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    //MARK: UITableViewDelegate
    
    override func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
		...
    }

```

![全画面_2014_07_22_12_02.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/c6646cb9-4561-c9fc-2044-5e14351dea2f.jpeg "全画面_2014_07_22_12_02.jpg")

### 参考 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まで以下のようなワーニングが出ていました。

![Main_storyboard_—_Edited.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/f9addd32-3fc0-5dbf-8779-8952a922c8f0.jpeg "Main_storyboard_—_Edited.jpg")


![Main_storyboard_—_Edited.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/ae013eb4-8c94-5538-74d2-187c1986d3c0.jpeg "Main_storyboard_—_Edited.jpg")


## 感想

UIntのIntの使い分けはコンバージョンの記述が増え、~~IBOutletのオプショナルもアンラップの記述が増えるので~~ちょっと残念です。

アクセスコントロールはみんなが待望していたのでありがたいですね。ライブラリ配布の懸念もひとつ解消されました。