Xcode 7で追加されたSwift用Objective-Cマクロ

# はじめに
Xcode 7（iOS 9.0 / OS X 10.11 / watchOS 2.0, Apple LLVM version 7.0.0）では、SwiftからObjective-Cを使いやすくするための以下の4つのマクロが追加されている。

```objc
NS_SWIFT_UNAVAILABLE(_msg)
NS_REFINED_FOR_SWIFT
NS_SWIFT_NAME(_name)
NS_SWIFT_NOTHROW
```

# NS_SWIFT_UNAVAILABLE(_msg)
`Foundation/NSObjCRuntime.h`

```objc
#define NS_SWIFT_UNAVAILABLE(_msg) CF_SWIFT_UNAVAILABLE(_msg)
```

`CoreFoundation/CFAvailability.h`

```c
#if __has_feature(attribute_availability_swift)
#define CF_SWIFT_UNAVAILABLE(_msg) __attribute__((availability(swift, unavailable, message=_msg)))
#else
#define CF_SWIFT_UNAVAILABLE(_msg)
#endif
```

いくつかのObjective-CインターフェイスはSwiftインターフェイスとして公開されるのにふさわしくない、または必要でないかもしれない。Objective-Cの宣言がSwiftによってインポートされないようにするために、`NS_SWIFT_UNAVAILABLE(_msg)`を利用すること。APIコンシューマに存在するかもしれない代案を指示するメッセージを引数に渡す。

例えば、キーと値のペアの可変長引数を取る簡易イニシャライザを提供するObjective-Cクラスは、Swiftコンシューマに代わりに辞書リテラルを利用ことを忠告する：

```objc
+ (instancetype)collectionWithKeysAndValues:(id)firstKey, ... NS_SWIFT_UNAVAILABLE("Use a dictionary literal instead");
```

Swiftコードから`+collectionWithKeysAndValues:`を呼び出そうとするとコンパイルエラーになる。

# NS_REFINED_FOR_SWIFT
`Foundation/NSObjCRuntime.h`

```objc
#define NS_REFINED_FOR_SWIFT CF_REFINED_FOR_SWIFT
```

`CoreFoundation/CFBase.h`

```c
#if __has_attribute(swift_private)
# define CF_REFINED_FOR_SWIFT __attribute__((swift_private))
#else
# define CF_REFINED_FOR_SWIFT
#endif
```

`NS_REFINED_FOR_SWIFT`マクロは、元の実装を有効にしたまま、Swiftで同じAPIの改良版を提供するためにObjective-Cの宣言を移動するために使用することができる。（例えば、`Class`を取るObjective-CのAPIはSwiftでより的確なパラメータ型を提供することができる。）

`NS_REFINED_FOR_SWIFT`マクロは異なる宣言で動作が異なる：

* 初期化メソッドは、最初の外部パラメータ名の前に付加された“__”を持つSwiftのイニシャライザとしてインポートされる。

    ```objc
    - (instancetype)initWithClassName:(NSString *)name NS_REFINED_FOR_SWIFT;
    ```

    ```swift
    init(__className: String)
    ```

* 他のメソッドは、そのベース名の前に“__”が付加されてインポートされる。

    ```objc
    - (NSString *)displayNameForMode:(DisplayMode)mode NS_REFINED_FOR_SWIFT;
    ```

    ```swift
    func __displayNameForMode(mode: DisplayMode) -> String
    ```

* サブスクリプトメソッドは他のメソッドと同様に扱われ、サブスクリプトとしてインポートされない。
* 他の宣言は、その名前の前に付加される“__”を持つ。

    ```objc
    @property DisplayMode mode NS_REFINED_FOR_SWIFT;
    ```

    ```swift
    var __mode: DisplayMode { get set }
    ```

# NS_SWIFT_NAME(_name)

`Foundation/NSObjCRuntime.h`

```objc
#define NS_REFINED_FOR_SWIFT CF_REFINED_FOR_SWIFT
```

`CoreFoundation/CFBase.h`

```c
#if __has_attribute(swift_name)
# define CF_SWIFT_NAME(_name) __attribute__((swift_name(#_name)))
#else
# define CF_SWIFT_NAME(_name)
#endif
```

`NS_SWIFT_NAME`マクロは、その定数がSwiftにきれいにマップされない列挙型のインポートを制御するために使用することができる。例えば：

```objc
typedef NS_ENUM(NSInteger, DisplayMode) {
  DisplayMode256Colors NS_SWIFT_NAME(With256Colors),
  DisplayModeThousandsOfColors,
  DisplayModeMillionsOfColors
};
```

これは以下のようにSwiftにインポートされる：

```swift
@objc enum DisplayMode : Int {
  case With256Colors
  case ThousandsOfColors
  case MillionsOfColors
}
```

このマクロは、ファクトリメソッドがイニシャライザとしてインポートされているかどうかを制御するためにも使用することができる。例えば：

```objc
@interface MyController : UIViewController
+ (instancetype)standardControllerForURLKind:(URLKind)kind NS_SWIFT_NAME(init(URLKind:));
@end
```

これは、自動ファクトリメソッドのインポートの規則に従っていない場合でも、以下のようにSwiftにインポートされる：

```swift
class MyController : UIViewController {
  init(URLKind kind: URLKind)
}
```

# NS_SWIFT_NOTHROW
`Foundation/NSObjCRuntime.h`

```objc
#if __has_attribute(swift_error)
#define NS_SWIFT_NOTHROW __attribute__((swift_error(none)))
#else
#define NS_SWIFT_NOTHROW
#endif
```

スローするメソッドとしてSwiftによってインポートされないようにするために`NSError`を生成するObjective-Cメソッドの宣言には、`NS_SWIFT_NOTHROW`マクロを利用すること。

例：

`Foundation/NSURL.h`

```objc
- (BOOL)checkResourceIsReachableAndReturnError:(NSError **)error NS_SWIFT_NOTHROW NS_AVAILABLE(10_6, 4_0);
```