Guides and Sample Code

Developer

Using Swift with Cocoa and Objective-C (Swift 4.1)

iBooks
On This Page

Interacting with Objective-C APIs
Objective-C APIとの相互作用

Interoperability is the ability to interface between Swift and Objective-C in either direction, letting you access and use pieces of code written in one language in a file of the other language. As you begin to integrate Swift into your app development workflow, it’s a good idea to understand how you can leverage interoperability to redefine, improve, and enhance the way you write Cocoa apps.
相互運用性は、スウィフトとObjective-Cの間でどちらの方向からでも調和させ、あなたに一方の言語で書かれるコード断片を他方の言語のファイルの中でアクセスおよび使用させる能力です。あなたがスウィフトをあなたのアプリ開発ワークフローに組み込み始めるとき、あなたがあなたがココア・アプリを書く方法をとらえ直して、向上させて、強化するために、どのように相互運用性を使って小さな労力で大きな成果を得られるようにできるか理解することは良い考えです。

One important aspect of interoperability is that it lets you work with Objective-C APIs when writing Swift code. After you import an Objective-C framework, you can instantiate classes from it and interact with them using native Swift syntax.
相互運用性の1つの重要な面は、スウィフトコードを書くとき、それがあなたにObjective-C APIを扱わせるということです。あなたがObjective-Cフレームワークをインポートしたあと、あなたはそれからのクラスをインスタンス化することができて、スウィフト本来の構文を使ってそれらと相互に作用することができます。

Initialization
初期化

To instantiate an Objective-C class in Swift, you call one of its initializers using Swift initializer syntax.
Objective-Cクラスをスウィフトにおいてインスタンス化するために、あなたはそれのイニシャライザのうちの1つをスウィフト初期化構文を使って呼び出します。

Objective-C initializers begin with init, or initWith: if the initializer takes one or more arguments. When an Objective-C initializer is imported by Swift, the init prefix becomes an init keyword to indicate that the method is a Swift initializer. If the initializer takes an argument, the With is removed and the rest of the selector is divided up into named parameters accordingly.
Objective-Cイニシャライザは、initで、またはイニシャライザがひとつ以上の引数をとるならばinitWith:で始まります。Objective-Cイニシャライザがスウィフトによってインポートされる時、init接頭辞はinitキーワードになって、そのメソッドがスウィフトイニシャライザであることを指し示します。イニシャライザが引数をとるならば、Withは取り除かれて残りのセレクタが名前付きパラメーターへとそれらしく分離されます。

Consider the following Objective-C initializer declarations:
以下のObjective-Cイニシャライザ宣言を考えてみてください:

  1. - (instancetype)init;
  2. - (instancetype)initWithFrame:(CGRect)frame
  3. style:(UITableViewStyle)style;

Here are the equivalent Swift initializer declarations:
ここに同等のスウィフトイニシャライザ宣言があります:

  1. init() { /* ... */ }
  2. init(frame: CGRect, style: UITableViewStyle) { /* ... */ }

The differences between Objective-C and Swift syntax are all the more apparent when instantiating objects.
Objective-Cとスウィフト構文の間の違いは、オブジェクトをインスタンス化するとき全て明らかになります。

In Objective-C, you do this:
Objective-Cでは、あなたはこうします:

  1. UITableView *myTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];

In Swift, you do this:
スウィフトでは、あなたはこうします:

  1. let myTableView: UITableView = UITableView(frame: .zero, style: .grouped)

Notice that you don’t need to call alloc; Swift handles this for you. Notice also that “init” doesn’t appear anywhere when calling the Swift-style initializer.
あなたがallocを呼ぶ必要がないことに注意してください;スウィフトは、これをあなたの代わりに処理します。またスウィフト形式のイニシャライザを呼ぶとき「init」がどこにも現れないことに注目してください。

You can provide an explicit type when assigning to a constant or variable, or you can omit the type and have Swift infer the type automatically from the initializer.
あなたは、定数または変数に割り当てする時に明示的な型を提供することができます、またはあなたは型を省略してスウィフトに型をイニシャライザから自動的に推論させることができます。

  1. let myTextField = UITextField(frame: CGRect(x: 0.0, y: 0.0, width: 200.0, height: 40.0))

These UITableView and UITextField objects are the same objects that you’d instantiate in Objective-C. You can use them in the same way you would in Objective-C, accessing any properties and calling any methods defined on their respective types.
これらのUITableViewUITextFieldオブジェクトは、それらがObjective-Cでインスタンス化するのと同じオブジェクトです。あなたは、それらをあなたがObjective-Cでするのと同じ方法で使って、それらの各自の型上で定義される、どんなプロパティにでもアクセスして、どんなメソッドでも呼び出すことができます。

Class Factory Methods and Convenience Initializers
クラスファクトリメソッドと便宜イニシャライザ

For consistency and simplicity, Objective-C class factory methods are imported as convenience initializers in Swift. This allows them to be used with the same syntax as initializers.
一貫性と単純さのために、Objective-Cクラスファクトリメソッドは、便宜イニシャライザとしてスウィフトにインポートされます。これは、それらにイニシャライザと同じ構文で使用されることを可能にします。

For example, whereas in Objective-C you would call this factory method like this:
例えば、Objective-Cではあなたはこのクラスファクトリメソッドこのように呼び出しますが:

  1. UIColor *color = [UIColor colorWithRed:0.5 green:0.0 blue:0.5 alpha:1.0];

In Swift, you call it like this:
スウィフトでは、あなたはそれをこのように呼び出します:

  1. let color = UIColor(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0)

Failable Initialization
失敗できる初期化

In Objective-C, initializers directly return the object they initialize. To inform the caller when initialization has failed, an Objective-C initializer can return nil. In Swift, this pattern is built into a language feature called failable initialization.
Objective-Cでは、イニシャライザは直接にそれが初期化したオブジェクトを返します。初期化が失敗した時に呼び出し側に報告するために、Objective-Cイニシャライザはnilを返すことができます。スウィフトでは、このよくある操作は失敗できる初期化と呼ばれる言語機能に組み込まれます。

Many Objective-C initializers in system frameworks have been audited to indicate whether initialization can fail. You can indicate whether initializers in your own Objective-C classes can fail using nullability annotations, as described in Nullability and Optionals. Objective-C initializers that indicate whether they’re failable are imported as either init(...)—if initialization cannot fail—or init?(...)—if initialization can fail. Otherwise, Objective-C initializers are imported as init!(...).
システムフレームワークの中の多くのObjective-Cイニシャライザは、初期化が失敗する可能性があるかどうか検査されてしまっています。あなたは、あなた独自のObjective-Cクラスの中のイニシャライザが失敗できるかどうかをヌル許可注釈を使って指し示すことができます、それはヌル許可とオプショナルで記述されます。それらが失敗できるかどうか指し示すObjective-Cイニシャライザは、初期化が失敗できないならば ― init(...)、または初期化が失敗できるならば ― init?(...)、このどちらかでインポートされます。それ以外では、Objective-Cイニシャライザは、init!(...)としてインポートされます。

For example, the UIImage(contentsOfFile:) initializer can fail to initialize a UIImage object if an image file doesn’t exist at the provided path. You can use optional binding to unwrap the result of a failable initializer if initialization is successful.
例えば、UIImage(contentsOfFile:)イニシャライザは、与えられたパスでファイルが存在しないならば、UIImageオブジェクトを初期化するのに失敗する可能性があります。あなたはオプショナル束縛を使って、初期化がうまくいったならば失敗できるイニシャライザの結果をアンラップすることができます。

  1. if let image = UIImage(contentsOfFile: "MyImage.png") {
  2. // loaded the image successfully (画像をうまく読み込んだ)
  3. } else {
  4. // could not load the image (画像を読み込めなかった)
  5. }

Accessing Properties
プロパティにアクセスする

Objective-C property declarations using the @property syntax are imported as Swift properties in the following way:
Objective-Cプロパティ宣言で@property構文を使っているものは、スウィフトプロパティとして以下の方法でインポートされます:

  • Properties with the nullability property attributes (nonnull, nullable, and null_resettable) are imported as Swift properties with optional or nonoptional type as described in Nullability and Optionals.
    ヌル許可プロパティ属性(nonnullnullable、そしてnull_resettable)を使ったプロパティは、スウィフトプロパティとしてインポートされるのにオプショナルまたは非オプショナル型を使います、ヌル許可とオプショナルで記述されるように。

  • Properties with the readonly property attribute are imported as Swift computed properties with a getter ({ get }).
    readonlyプロパティ属性を使うプロパティは、スウィフト計算プロパティとしてインポートされるのにゲッター({ get })を使います。

  • Properties with the weak property attribute are imported as Swift properties marked with the weak keyword (weak var).
    weakプロパティ属性を使うプロパティは、weakキーワード(weak var)で印されるスウィフトプロパティとしてインポートされます。

  • Properties with an ownership property attribute other than weak (that is, assign, copy, strong, or unsafe_unretained) are imported as Swift properties with the appropriate storage.
    weakとは別の所有者プロパティ属性(すなわち、assigncopystrong、またはunsafe_unretained)を持つプロパティは、スウィフトプロパティとしてインポートされるのに適切なストレージを使います。

  • Properties with the class property attribute are imported as Swift type properties.
    classプロパティ属性を持つプロパティは、スウィフト型プロパティとしてインポートされます。

  • Atomicity property attributes (atomic and nonatomic) are not reflected in the corresponding Swift property declaration, but the atomicity guarantees of the Objective-C implementation still hold when the imported property is accessed from Swift.
    原子性プロパティ属性(atomicnonatomic)は、スウィフトプロパティ宣言に反映されません、しかしObjective-C実装の原子性担保はインポートされたプロパティがスウィフトからアクセスされる時に依然として保持されます。

  • Accessor property attributes (getter= and setter=) are ignored by Swift.
    アクセッサプロパティ属性(getter=setter=)は、スウィフトによって無視されます。

You access properties on Objective-C objects in Swift using dot syntax, using the name of the property without parentheses.
あなたは、Objective-Cオブジェクト上のプロパティにスウィフトにおいてドット構文によって、そのプロパティの名前を丸括弧なして使ってアクセスします。

For example, you can set the textColor and text properties of a UITextField object with the following code:
例えば、あなたはあるUITextFieldオブジェクトのtextColortextプロパティを設定するにの以下のコードを使うことができます:

  1. myTextField.textColor = .darkGray
  2. myTextField.text = "Hello world"

Objective-C methods that return a value and take no arguments can be called like an Objective-C property using dot syntax. However, these are imported by Swift as instance methods, as only Objective-C @property declarations are imported by Swift as properties. Methods are imported and called as described in Working with Methods.
値を返して引数を取らないObjective-Cメソッドは、Objective-Cプロパティのように呼び出すことがドット構文を使って行えます。しかしながら、それらはスウィフトによってインスタンスメソッドのようにインポートされます、Objective-Cの@property宣言だけはスウィフトによってプロパティとしてインポートされます。メソッドは、メソッドを扱うで記述されるように、インポートされ呼び出されます。

Working with Methods
メソッドを扱う

You can call Objective-C methods from Swift using dot syntax.
あなたは、Objective-Cメソッドをスウィフトからドット構文を使って呼び出すことができます。

When Objective-C methods are imported into Swift, the first part of the Objective-C selector becomes the base method name and appears before the parentheses. The first argument appears immediately inside the parentheses, without a name. The rest of the selector pieces correspond to argument names and appear inside the parentheses. All selector pieces are required at the call site.
Objective-Cメソッドがスウィフトにインポートされるとき、Objective-Cセレクタの最初の部分は、基盤となるメソッド名になって、丸括弧の前に現れます。最初の引数は、名前なしで、丸括弧の直ぐ内側に現れます。残りのセレクタ片は、引数名に相当して、括弧の内側に現れます。全てのセレクタ片は、呼び出し現場で必須とされます。

For example, whereas in Objective-C you would do this:
例えば、Objective-Cではあなたがこうするのに対して:

  1. [myTableView insertSubview:mySubview atIndex:2];

In Swift, you do this:
スウィフトでは、あなたはこうします:

  1. myTableView.insertSubview(mySubview, at: 2)

If you’re calling a method with no arguments, you must still include parentheses.
あなたが引数なしでメソッドを呼んでいる場合、あなたはそれでも括弧を含めなければなりません。

  1. myTableView.layoutIfNeeded()

id Compatibility
id互換性

The Objective-C id type is imported by Swift as the Any type. At compile time and runtime, the compiler introduces a universal bridging conversion operation when a Swift value or object is passed into Objective-C as an id parameter. When id values are imported into Swift as Any, the runtime automatically handles bridging back to either class references or Swift value types.
Objective-C id型は、スウィフトによってAny型としてインポートされます。コンパイル時および実行時に、コンパイラは全般的ブリッジ変換演算を、スウィフトの値やオブジェクトがObjective-Cへidパラメータとして渡される時に導入します。id値がスウィフトへAnyとしてインポートされる時、ランタイムは自動的にクラス参照またはスウィフト値型のどちらかへ戻すブリッジを取り扱います。

  1. var x: Any = "hello" as String
  2. x as? String // String with value "hello"
  3. x as? NSString // NSString with value "hello"
  4. x = "goodbye" as NSString
  5. x as? String // String with value "goodbye"
  6. x as? NSString // NSString with value "goodbye"

Downcasting Any
Anyのダウンキャスト

When working with objects of type Any where the underlying type is known or could be reasonably determined, it is often useful to downcast those objects to a more specific type. However, because the Any type can refer to any type, a downcast to a more specific type is not guaranteed to succeed.
基礎をなす型が知られているかまずまず判定されることができるところの型Anyのオブジェクトを扱う時、そのようなオブジェクトをもっとはっきりした型へダウンキャストするのはしばしば便利です。しかしながら、Any型はあらゆる型を参照できることから、より具体的な型へダウンキャウトすることは成功することを保証されません。

You can use the conditional type cast operator (as?), which returns an optional value of the type you are trying to downcast to:
あなたは、条件型キャスト演算子(as?)を使うことができます、それは、あなたがそれへとダウンキャストを試みている型のオプショナルの値を返します:

  1. let userDefaults = UserDefaults.standard
  2. let lastRefreshDate = userDefaults.object(forKey: "LastRefreshDate") // lastRefreshDate is of type Any? (lastRefreshDateは型Any?です)
  3. if let date = lastRefreshDate as? Date {
  4. print("\(date.timeIntervalSinceReferenceDate)")
  5. }

If you are certain of the type of the object, you can use the forced downcast operator (as!) instead.
あなたがそのオプジェクトの型について確信をもつならば、あなたは強制ダウンキャスト演算子(as!)を代わりに使うことができます。

  1. let myDate = lastRefreshDate as! Date
  2. let timeInterval = myDate.timeIntervalSinceReferenceDate

However, if a forced downcast fails, a runtime error is triggered:
しかしながら、強制型キャストが失敗するならば、実行時エラーが引き起こされます:

  1. let myDate = lastRefreshDate as! String // Error

Dynamic Method Lookup
動的メソッド検索

Swift also includes an AnyObject type that represents some kind of object and has the special ability to look up any @objc method dynamically. This allows you to write maintain flexibility of untyped access to Objective-C APIs that return id values.
スウィフトはまたAnyObject型を含んでいます。それは何かわからないある種類のオブジェクトを表します、そしてどれかの@objcメソッドを動的に検索する特別な能力を持ちます。これがあなたに書くことを可能にするのは、id値を返すObjective-C APIに対する型なしでのアクセスの柔軟性の維持です。

For example, you can assign an object of any class type to a constant or variable of AnyObject type and reassign a variable to an object of a different type. You can also call any Objective-C method and access any property on an AnyObject value without casting to a more specific class type.
例えば、あなたはどんなクラス型のオブジェクトでもAnyObject型の定数や変数に代入できます、そしてある変数を異なる型のオブジェクトへ再度代入できます。あなたはまた、あらゆるObjective-Cメソッドを呼び出すこと、そしてAnyObject値上のあらゆるプロパティにアクセスすることが、より具体的なクラス型にキャストすることなしに可能です。

  1. var myObject: AnyObject = UITableViewCell()
  2. myObject = NSDate()
  3. let futureDate = myObject.addingTimeInterval(10)
  4. let timeSinceNow = myObject.timeIntervalSinceNow

Unrecognized Selectors and Optional Chaining
識別不能セレクタとオプショナル連鎖

Because the specific type of an AnyObject value is not known until runtime, it is possible to inadvertently write unsafe code. In Swift as well as Objective-C, attempting to call a method that does not exist triggers an unrecognized selector error.
AnyObject値の具体的な型は実行時まで知られないことから、不注意に安全でないコードを書くことは可能です。スウィフトではObjective-C同様に、存在しないメソッドを呼び出す試みは、識別不能セレクタエラーの引き金となります。

For example, the following code compiles without a compiler warning, but triggers an error at runtime:
例えば、以下のコードは警告なしにコンパイルします、しかし実行時にエラーの引き金となります:

  1. myObject.character(at: 5)
  2. // crash, myObject doesn't respond to that method (失敗、myObjectはこのメソッドに応答することができません)

Swift uses optionals to guard against such unsafe behavior. When you call a method on a value of AnyObject type, that method call behaves like an implicitly unwrapped optional. You can use the same optional chaining syntax you would use for optional methods in protocols to optionally invoke a method on AnyObject.
スウィフトは、オプショナルを使用してこのような安全でない挙動の発生を防ぐことができます。あなたがAnyObject型の値上でメソッドを呼ぶとき、そのメソッド呼び出しは暗黙的にアンラップされるオプショナルのように振る舞います。あなたは、プロトコルにおいてオプショナルメソッドに対して使う同じオプショナル連鎖構文を使って、AnyObject上でメソッドを随意なものとして発動することができます。

For example, in the code listing below, the first and second lines are not executed because the count property and the character(at:) method do not exist on an NSDate object. The myCount constant is inferred to be an optional Int, and is set to nil. You can also use an iflet statement to conditionally unwrap the result of a method that the object may not respond to, as shown on line three.
例えば、下記のコード出力において、最初と2番目の行が実行されません、なぜなら、countプロパティとcharacter(at:)メソッドはNSDateオブジェクトには存在しないからです。myCount定数は、オプショナルのIntであると推論されて、nilに設定されます。あなたはまたiflet文を使用して、3行目で示されるように、条件付きでオブジェクトが応答しないかもしれないメソッドの結果をアンラップすることができます。

  1. // myObject has AnyObject type and NSDate value (myObjectはAnyObject型でNSDate値を持ちます)
  2. let myCount = myObject.count
  3. // myCount has Int? type and nil value (myCountはInt?型でnil値を持ちます)
  4. let myChar = myObject.character?(at: 5)
  5. // myChar has unichar? type and nil value (myCharはunichar?型でNSDatenilを持ちます)
  6. if let fifthCharacter = myObject.character?(at: 5) {
  7. print("Found \(fifthCharacter) at index 5")
  8. }
  9. // conditional branch not executed (条件分岐は実行されません)

Nullability and Optionals
ヌル許可とオプショナル

In Objective-C, you work with references to objects using raw pointers that could be NULL (referred to as nil in Objective-C). In Swift, all values—including structures and object references—are guaranteed to be non–null. Instead, you represent a value that could be missing by wrapping the type of the value in an optional type. When you need to indicate that a value is missing, you use the value nil. For more information about optionals, see Optionals in The Swift Programming Language (Swift 4.1).
Objective-Cでは、あなたはオブジェクトへの参照を、NULL(Objective-Cではnilと呼ばれます)であることができる生のポインターを使って扱います。スウィフトでは、すべての値は ― 構造体やオブジェクト参照を含めて ― 非nullであることを保証されます。代わりに、あなたは見つからない値を、その型の値をオプショナル型の中にラップすることによって表わします。あなたがある値が見つからないことを指し示す必要があるならば、あなたは値nilを使います。オプショナルについての更なる情報として、オプショナルスウィフトプログラミング言語(Swift 4.1)において見てください。

Objective-C can use nullability annotations to designate whether a parameter type, property type, or return type, can have a NULL or nil value. Individual type declarations can be audited using the _Nullable and _Nonnull annotations, individual property declarations can be audited using the nullable, nonnull and null_resettable property attributes, or entire regions can be audited for nullability using the NS_ASSUME_NONNULL_BEGIN and NS_ASSUME_NONNULL_END macros. If no nullability information is provided for a type, Swift cannot distinguish between optional and nonoptional references, and imports it as an implicitly unwrapped optional.
Objective-Cは、ヌル許可注釈を使って、あるパラメーター型、プロパティ型、または戻り値型がNULLまたはnil値を持つことが可能かどうか任命できます。個々の型宣言は_Nullable_Nonnull注釈を使って監査されることができます、個々のプロパティ宣言はnullablenonnull、そしてnull_resettableプロパティ属性を使って監査されることができます、または領域全体がヌル許可について監査されることがNS_ASSUME_NONNULL_BEGINNS_ASSUME_NONNULL_ENDマクロを使って可能です。ヌル許可情報がある型に提供されないならば、スウィフトはオプショナル参照と非オプショナル参照とを見分けることができません、そしてそれを暗黙的にアンラップされるオプショナルとしてインポートします。

  • Types declared to be nonnullable, either with a _Nonnull annotation or in an audited region, are imported by Swift as a nonoptional.
    非ヌル可能として定義された型、_Nonnull注釈を使ってまたはある監査された領域の中の両方、は、スウィフトによって非オプショナルとしてインポートされます。

  • Types declared to be nullable with a _Nullable annotation, are imported by Swift as an optional.
    ヌル可能として_Nullable注釈を使って定義された型は、スウィフトによってオプショナルとしてインポートされます。

  • Types declared without a nullability annotation are imported by Swift as an implicitly unwrapped optional.
    ヌル可能注釈を使わずに定義された型は、スウィフトによって暗黙的にアンラップされるオプショナルとしてインポートされます。

For example, consider the following Objective-C declarations:
例として、以下のObjective-C宣言を考えてください:

  1. @property (nullable) id nullableProperty;
  2. @property (nonnull) id nonNullProperty;
  3. @property id unannotatedProperty;
  4. NS_ASSUME_NONNULL_BEGIN
  5. - (id)returnsNonNullValue;
  6. - (void)takesNonNullParameter:(id)value;
  7. NS_ASSUME_NONNULL_END
  8. - (nullable id)returnsNullableValue;
  9. - (void)takesNullableParameter:(nullable id)value;
  10. - (id)returnsUnannotatedValue;
  11. - (void)takesUnannotatedParameter:(id)value;

Here’s how they’re imported by Swift:
ここに、どのようにそれらがスウィフトにインポートされるかがあります:

  1. var nullableProperty: Any?
  2. var nonNullProperty: Any
  3. var unannotatedProperty: Any!
  4. func returnsNonNullValue() -> Any
  5. func takesNonNullParameter(value: Any)
  6. func returnsNullableValue() -> Any?
  7. func takesNullableParameter(value: Any?)
  8. func returnsUnannotatedValue() -> Any!
  9. func takesUnannotatedParameter(value: Any!)

Most of the Objective-C system frameworks, including Foundation, already provide nullability annotations, allowing you to work with values in an idiomatic and type-safe manner.
ほとんどのObjective-Cシステムフレームワーク、Foundationを含む、は、すでにヌル可能注釈を提供し、あなたに慣用句的な型安全な手法で値を扱えるようにします。

Bridging Optionals to Nonnullable Objects
オプショナルをnull不可オブジェクトへブリッジする

Swift bridges optional values to nonnullable Objective-C objects according to whether the optional contains an underlying, wrapped value. If the optional is nil, Swift bridges the nil value as an NSNull instance. Otherwise, Swift bridges the optional as its unwrapped value. For example, you see this behavior when an optional is passed to an Objective-C API that takes a nonnull id and when an array of optional items ([T?]) is bridged to an NSArray.
スウィフトは、オプショナル値をnull不可Objective-Cオブジェクトへと、そのオプショナルがその下に隠している、ラップされた値を持つかどうかに従ってブリッジします。そのオプショナルがnilならば、スウィフトはそのnil値をNSNullインスタンスとしてブリッジします。そうでなければ、スウィフトはそのオプショナルをそれのアンラップされた値としてブリッジします。例えば、あなたはこの挙動を、あるオプショナルが非null idをとるObjective-C APIに渡される時、およびオプショナル項目([T?])からなる配列がNSArrayへブリッジされる時に見ます。

The following code shows how String? instances bridge to Objective-C depending on their value.
以下のコードは、どのようにString?インスタンスがObjective-Cへとそれの値に基づいてブリッジするかを示します。

  1. @implementation OptionalBridging
  2. + (void)logSomeValue:(nonnull id)valueFromSwift {
  3. if ([valueFromSwift isKindOfClass: [NSNull class]]) {
  4. os_log(OS_LOG_DEFAULT, "Received an NSNull value.");
  5. } else {
  6. os_log(OS_LOG_DEFAULT, "%s", [valueFromSwift UTF8String]);
  7. }
  8. }
  9. @end

Because the type of the valueFromSwift parameter is id, it’s imported in the Swift code below as the Swift type Any. However, because passing an optional when an Any was expected is uncommon, the optionals passed into the logSomeValue(_:) class method are explicitly cast to the Any type, which silences a compiler warning.
valueFromSwiftパラメータの型はidであるので、それは以下のスウィフトコードにおいてスウィフト型Anyとしてインポートされます。しかしながら、Anyが期待された時オプショナルを渡すことは普通でないため、logSomeValue(_:)メソッドへと渡されるオプショナルは明示的にAny型へキャストされます、それはコンパイラ警告を黙らせます。

  1. let someValue: String? = "Bridge me, please."
  2. let nilValue: String? = nil
  3. OptionalBridging.logSomeValue(someValue as Any) // Bridge me, please.
  4. OptionalBridging.logSomeValue(nilValue as Any) // Received an NSNull value. (NSNull値を受け取った。)

Protocol-Qualified Classes
プロトコル適格クラス

Objective-C classes qualified by one or more protocols are imported by Swift as protocol composition types. For example, given the following Objective-C property that refers to a view controller:
1つ以上のプロトコルによって適格にされるObjective-Cクラスは、スウィフトによってプロトコル合成型としてインポートされます。例えば、あるビューコントローラを参照する以下のObjective-Cプロパティを与えられて:

  1. @property UIViewController<UITableViewDataSource, UITableViewDelegate> * myController;

Here’s how Swift imports it:
ここにスウィフトがそれをインポートする方法があります:

  1. var myController: UIViewController & UITableViewDataSource & UITableViewDelegate

Objective-C protocol-qualified metaclasses are imported by Swift as protocol metatypes. For example, given the following Objective-C method that performs an operation on the specified class:
Objective-Cのプロトコル適格メタクラスは、スウィフトによってプロトコルメタタイプとしてインポートされます。例えば、指定されたクラス上である演算を実行する以下のObjective-Cメソッドを与えられて:

  1. - (void)doSomethingForClass:(Class<NSCoding>)codingClass;

Here’s how Swift imports it:
ここにスウィフトがそれをインポートする方法があります:

  1. func doSomething(for codingClass: NSCoding.Type)

Lightweight Generics
軽量総称体

Objective-C type declarations using lightweight generic parameterization are imported by Swift with information about the type of their contents preserved. For example, given the following Objective-C property declarations:
軽量総称体パラメーター化を使っているObjective-C宣言は、それらの保管される内容についての情報を使ってスウィフトによってインポートされます。例えば、以下のObjective-Cプロパティを与えられて:

  1. @property NSArray<NSDate *> *dates;
  2. @property NSCache<NSObject *, id<NSDiscardableContent>> *cachedData;
  3. @property NSDictionary <NSString *, NSArray<NSLocale *>> *supportedLocales;

Here’s how Swift imports them:
ここにどのようにスウィフトがそれらをインポートするかがあります:

  1. var dates: [Date]
  2. var cachedData: NSCache<NSObject, NSDiscardableContent>
  3. var supportedLocales: [String: [Locale]]

A parameterized class written in Objective-C is imported into Swift as a generic class with the same number of type parameters. All Objective-C generic type parameters imported by Swift have a type constraint that requires that type to be a class (T: Any). If the Objective-C generic parameterization specifies a class qualification, the imported Swift class has a constraint that requires that type to be a subclass of the specified class. If the Objective-C generic parameterization specifies a protocol qualification, the imported Swift class has a constraint that requires that type to conform to the specified protocol. For an unspecialized Objective-C type, Swift infers the generic parameterization for the imported class type constraints. For example, given the following Objective-C class and category declarations:
Objective-Cにおいて書かれたパラメータ化されたクラスは、同じ数の型パラメータを持つ総称体クラスとしスウィフトにインポートされます。スウィフトによってインポートされる全てのObjective-C総称体型パラメータは、ある型制約を持ちます、それはあるクラス(T: Any)であることをその型に要求します。あるクラス資格をObjective-C総称体パラメータ化が指定するならば、インポートされたスウィフトクラスはある制約を持ちます、それは指定されたクラスのサブクラスであることをその型に要求します。あるプロトコル資格をObjective-C総称体パラメータ化が指定するならば、インポートされたスウィフトクラスはある制約を持ちます、それは指定されたプロトコルに準拠することをその型に要求します。特殊化されないObjective-C型に対して、スウィフトは総称体パラメータ化をインポートされたクラス型制約に対して推測します。例えば、以下のObjective-Cクラスおよびカテゴリ定義を与えられて:

  1. @interface List<T: id<NSCopying>> : NSObject
  2. - (List<T> *)listByAppendingItemsInList:(List<T> *)otherList;
  3. @end
  4. @interface ListContainer : NSObject
  5. - (List<NSValue *> *)listOfValues;
  6. @end
  7. @interface ListContainer (ObjectList)
  8. - (List *)listOfObjects;
  9. @end

Here’s how they’re imported by Swift:
ここに、どのようにそれらがスウィフトにインポートされるかがあります:

  1. class List<T: NSCopying> : NSObject {
  2. func listByAppendingItemsInList(otherList: List<T>) -> List<T>
  3. }
  4. class ListContainer : NSObject {
  5. func listOfValues() -> List<NSValue>
  6. }
  7. extension ListContainer {
  8. func listOfObjects() -> List<NSCopying>
  9. }

Extensions
拡張

A Swift extension is similar to an Objective-C category. Extensions expand the behavior of existing classes, structures, and enumerations, including those defined in Objective-C. You can define an extension on a type from either a system framework or one of your own custom types. Simply import the appropriate module, and refer to the class, structure, or enumeration by the same name that you would use in Objective-C.
スウィフトの拡張は、Objective-Cのカテゴリーに似ています。拡張は、既存のクラス、構造体、そして列挙の挙動を、Objective-Cで定義されるそれらを含めて、発展させます。あなたは、システム・フレームワークから、またはあなた独自のあつらえの型の1つから、そのどちらかの型の上で拡張を定義することができます。単に適切なモジュールをインポートしてください、そしてあなたがObjective-Cで使うだろうのと同じ名前によって、そのクラス、構造体、または列挙を参照してください。

For example, you can extend the UIBezierPath class to create a simple Bézier path with an equilateral triangle, based on a provided side length and starting point.
例えば、あなたはUIBezierPathクラスを拡張して、二等辺三角形を使った単純な「ベジェ」パスを作成するようにできます、それは提供された辺長と開始点に基づきます。

  1. extension UIBezierPath {
  2. convenience init(triangleSideLength: CGFloat, origin: CGPoint) {
  3. self.init()
  4. let squareRoot = CGFloat(sqrt(3.0))
  5. let altitude = (squareRoot * triangleSideLength) / 2
  6. move(to: origin)
  7. addLine(to: CGPoint(x: origin.x + triangleSideLength, y: origin.y))
  8. addLine(to: CGPoint(x: origin.x + triangleSideLength / 2, y: origin.y + altitude))
  9. close()
  10. }
  11. }

You can use extensions to add properties (including class and static properties). However, these properties must be computed; extensions can’t add stored properties to classes, structures, or enumerations.
あなたは、拡張を使ってプロパティ(クラスや静的なプロパティを含む)を加えることができます。しかし、これらのプロパティは、計算されなければなりません;拡張は、格納プロパティをクラス、構造体、または列挙に加えることができません。

This example extends the CGRect structure to contain a computed area property:
この例は、CGRect構造体を拡張して、計算areaプロパティを含むようにします:

  1. extension CGRect {
  2. var area: CGFloat {
  3. return width * height
  4. }
  5. }
  6. let rect = CGRect(x: 0.0, y: 0.0, width: 10.0, height: 50.0)
  7. let area = rect.area

You can also use extensions to add protocol conformance to a class without subclassing it. If the protocol is defined in Swift, you can also add conformance to it to structures or enumerations, whether defined in Swift or Objective-C.
あなたはまた拡張を使って、プロトコル準拠をあるクラスに、それをサブクラス化することなく加えることができます。そのプロトコルがスウィフトにおいて定義されるならば、スウィフトまたはObjective-Cで定義されるかに関係なく、あなたは同様にそれに対する準拠を構造体または列挙に加えることができます。

You cannot use extensions to override existing methods or properties on Objective-C types.
あなたは、Objective-C型上での既存のメソッドまたはプロパティをオーバーライドするために拡張を使うことができません。

Closures
クロージャ

Objective-C blocks are automatically imported as Swift closures with Objective-C block calling convention, denoted by the @convention(block) attribute. For example, here is an Objective-C block variable:
Objective-Cのブロックは、Objective-Cのブロック呼出規約をもつスウィフトのクロージャとして自動的にインポートされ、それは@convention(block)属性で分かります。例えば、ひとつのObjective-Cブロック変数がここにあります:

  1. void (^completionBlock)(NSData *) = ^(NSData *data) {
  2. // ...
  3. }

And here’s what it looks like in Swift:
そして、それがスウィフトではどんなものになるかがここにあります:

  1. let completionBlock: (Data) -> Void = { data in
  2. // ...
  3. }

Swift closures and Objective-C blocks are compatible, so you can pass Swift closures to Objective-C methods that expect blocks. Swift closures and functions have the same type, so you can even pass the name of a Swift function.
スウィフトのクロージャとObjective-Cのブロックは互換性を持つので、ブロックを要求するObjective-Cメソッドに、あなたはスウィフトクロージャを渡すことができます。スウィフトのクロージャと関数は同じ型を持つので、あなたはスウィフト関数の名前を渡しさえすることができます。

Closures have similar capture semantics as blocks but differ in one key way: Variables are mutable rather than copied. In other words, the behavior of __block in Objective-C is the default behavior for variables in Swift.
クロージャは、ブロックとしての類似したキャプチャ意味論を持ちますが、1つの重要なやり方において異なります:変数は、コピーされるのではなく、可変です。言い換えると、Objective-Cでの__blockの挙動は、スウィフトの中の変数のための初期状態での挙動です。

Avoiding Strong Reference Cycles When Capturing self
強い参照循環を自身をキャプチャするときに避ける

In Objective-C, if you need to capture self in a block, it’s important to consider the memory management implications.
Objective-Cにおいて、あなたがselfをあるブロックにおいてキャプチャする必要があるならば、メモリ管理の影響を考慮することが重要です。

Blocks maintain strong references to any captured objects, including self. If self maintains a strong reference to the block, such as a copying property, this would create a strong reference cycle. To avoid this, you can instead have the block capture a weak reference to self:
ブロックは、selfを含めて、あらゆるキャプチャされるオブジェクトに対する強い参照を管理します。selfがブロックに対する強い参照を管理するならば、これは強い参照循環を作り出すでしょう。これを避けるために、あなたは代わりにブロックがselfに対する弱い参照をキャプチャするようにできます:

  1. __weak typeof(self) weakSelf = self;
  2. self.block = ^{
  3. __strong typeof(self) strongSelf = weakSelf;
  4. [strongSelf doSomething];
  5. };

Like blocks in Objective-C, closures in Swift also maintain strong references to any captured objects, including self. To prevent a strong reference cycle, you can specify self to be unowned in a closure’s capture list:
Objective-Cでのブロックのように、スウィフトでのクロージャもまた、selfを含めて、あらゆるキャプチャされたオブジェクトに対する強い参照を管理します。強い参照循環を防ぐために、あなたはselfunownedであるとクロージャのキャプチャリストにおいて指定することができます:

  1. self.closure = { [unowned self] in
  2. self.doSomething()
  3. }

For more information, see Resolving Strong Reference Cycles for Closures in The Swift Programming Language (Swift 4.1).
更なる情報として、クロージャのための強い参照循環の解消スウィフトプログラミング言語(Swift 4.1)で見てください。

Object Comparison
オブジェクト比較

There are two distinct types of comparison you can make between two objects in Swift. The first, equality (==), compares the contents of the objects. The second, identity (===), determines whether or not the constants or variables refer to the same object instance.
あなたがスウィフトにおいて2つのオブジェクトの間に作ることができる比較には2つの別個の型があります。1つめ、同等性==)は、オブジェクトの内容を比較します。2つめ、同一性===)は、定数または変数が同じオブジェクトインスタンスに言及するかどうかを確認します。

Swift provides default implementations of the == and === operators and adopts the Equatable protocol for objects that derive from the NSObject class. The default implementation of the == operator invokes the isEqual: method, and the default implementation of the === operator checks pointer equality. You should not override the equality or identity operators for types imported from Objective-C.
スウィフトは、=====演算子の省略時の実装を提供します、そしてEquatableプロトコルをNSObjectクラス由来のオブジェクトに対して採用します。==演算子の省略時の実装は、isEqual:メソッドを発動します、そして===演算子の省略時の実装はポインタの同等性を調べます。あなたは、Objective-Cからインポートされた型に対する同等性または同一性演算子をオーバーライドすべきではありません。

The base implementation of the isEqual: provided by the NSObject class is equivalent to an identity check by pointer equality. You can override isEqual: in a subclass to have Swift and Objective-C APIs determine equality based on the contents of objects rather than their identities. For more information about implementing comparison logic, see Object comparison in Cocoa Core Competencies.
NSObjectクラスによって提供されるisEqual:の基本実装は、ポインタ同等性による同一性確認に等しいものです。あなたは、isEqual:をサブクラスにおいてオーバーライドして、それらの同一性ではなくてオブジエクトの内容に基づいて同等性を判断するスウィフトとObjective-C APIを持つことができます。比較ロジックの実装についての更なる情報として、Object comparisonCocoa Core Competenciesで見てください。

Hashing
ハッシュ化

Swift imports Objective-C declarations of NSDictionary that don’t specify a class qualification for the key type as a Dictionary with the Key type AnyHashable. Similarly, NSSet declarations without a class-qualified object type are imported by Swift as a Set with the Element type AnyHashable. If an NSDictionary or NSSet declaration does parameterize its key or object type, respectively, that type is used instead. For example, given the following Objective-C declarations:
スウィフトは、キー型に対してクラス資格を指定しないNSDictionaryのObjective-C宣言を、KeyAnyHashableを持つDictionaryとしてインポートします。同様に、クラス適格オブジェクト型なしでのNSSet宣言は、スウィフトによってElementAnyHashableを持つSetとしてインポートされます。あるNSDictionaryまたはNSSet宣言がそれのキーまたはオブジェクト型をパラメータ化するならば、それぞれ、その型が代わりに使われます。例えば、以下のObjective-C宣言を与えられて:

  1. @property NSDictionary *unqualifiedDictionary;
  2. @property NSDictionary<NSString *, NSDate *> *qualifiedDictionary;
  3. @property NSSet *unqualifiedSet;
  4. @property NSSet<NSString *> *qualifiedSet;

Here’s how Swift imports them:
ここにどのようにスウィフトがそれらをインポートするかがあります:

  1. var unqualifiedDictionary: [AnyHashable: Any]
  2. var qualifiedDictionary: [String: Date]
  3. var unqualifiedSet: Set<AnyHashable>
  4. var qualifiedSet: Set<String>

The AnyHashable type is used by Swift when importing Objective-C declarations with an unspecified or id type that cannot be otherwise be imported as Any because the type needs to conform to the Hashable protocol. The AnyHashable type is implicitly converted from any Hashable type, and you can use the as? and as! operators to cast from AnyHashable to a more specific type.
AnyHashable型は、スウィフトによって、idまたは未指定型を持つObjective-C宣言をインポートする時に使われます、それはそうでなければAnyとしてインポートされることができません、なぜならその型はHashableプロトコルに準拠する必要があるからです。AnyHashable型は暗黙的に何らかのHashable型から変換されます、そしてあなたはas?およびas!演算子を使ってAnyHashableからより具体的な型へキャストできます。

For more information, see AnyHashable.
詳細は、AnyHashableを見てください。

Swift Type Compatibility
スウィフト型互換性

When you create a Swift class that descends from an Objective-C class, the class and its members—properties, methods, subscripts, and initializers—that are compatible with Objective-C are automatically available from Objective-C. This excludes Swift-only features, such as those listed here:
あなたがObjective-Cクラス由来のスウィフトクラスを作成するとき、そのクラスおよびObjective-C互換のそれのメンバー ― プロパティ、メソッド、添え字、そしてイニシャライザ ― は、自動的にObjective-Cから利用可能です。これは、ここに一覧にされるようなスウィフトのみの機能を除外します:

  • Generics
    総称体

  • Tuples
    タプル

  • Enumerations defined in Swift without Int raw value type
    Intの生の値型なしでスウィフトにおいて定義される列挙

  • Structures defined in Swift
    スウィフトにおいて定義される構造体

  • Top-level functions defined in Swift
    スウィフトにおいて定義されるトップレベル関数

  • Global variables defined in Swift
    スウィフトにおいて定義されるグローバル変数

  • Typealiases defined in Swift
    スウィフトにおいて定義される型エイリアス

  • Swift-style variadics
    スウィフト形式の可変長引数

  • Nested types
    入れ子にされた型

  • Curried functions
    カリー化関数

Swift APIs are translated into Objective-C similar to how Objective-C APIs are translated into Swift, but in reverse:
スウィフトのAPIは、Objective-C APIがスウィフトへと翻訳される方法と同じように、しかし逆に、Objective-Cへと翻訳されます:

  • Swift optional types are annotated as __nullable.
    スウィフトのオプショナル型は、__nullableとして注釈を付けられます。

  • Swift nonoptional types are annotated as __nonnull.
    スウィフトの非オプショナル型は、__nonnullとして注釈を付けられます。

  • Swift constant stored properties and computed properties become read-only Objective-C properties.
    スウィフトの定数格納プロパティと計算プロパティは、読出し専用Objecive-Cプロパティになります。

  • Swift variable stored properties become read-write Objective-C properties.
    スウィフトの変数格納プロパティは、読み書き両用のObjective-Cプロパティになります。

  • Swift type properties become Objective-C properties with the class property attribute.
    スウィフト型プロパティは、classプロパティ属性を持つObjective-Cプロパティになります。

  • Swift type methods become Objective-C class methods.
    スウィフトの型メソッドは、Objective-Cクラスメソッドになります。

  • Swift initializers and instance methods become Objective-C instance methods.
    スウィフトのイニシャライザとインスタンスメソッドは、Objective-Cインスタンスメソッドになります。

  • Swift methods that throw errors become Objective-C methods with an NSError ** parameter. If the Swift method has no parameters, AndReturnError: is appended to the Objective-C method name, otherwise error: is appended. If a Swift method does not specify a return type, the corresponding Objective-C method has a BOOL return type. If the Swift method returns a nonoptional type, the corresponding Objective-C method has an optional return type.
    エラーをスローするスウィフトメソッドは、NSError **パラメータを持つObjective-Cメソッドになります。そのスウィフトメソッドがパラメータを持たないならば、AndReturnError:がObjective-Cメソッド名に加えられ、そうでないならばerror:が加えられます。そのスウィフトメソッドが戻り型を指定しないならば、対応するObjective-CメソッドはBOOLの戻り型を持ちます。そのスウィフトメソッドが非オプショナル型を返すならば、対応するObjective-Cメソッドはオプショナルの戻り型を持ちます。

For example, consider the following Swift declaration:
例として、以下のスウィフト宣言を考えてください:

  1. class Jukebox: NSObject {
  2. var library: Set<String>
  3. var nowPlaying: String?
  4. var isCurrentlyPlaying: Bool {
  5. return nowPlaying != nil
  6. }
  7. class var favoritesPlaylist: [String] {
  8. // return an array of song names
  9. }
  10. init(songs: String...) {
  11. self.library = Set<String>(songs)
  12. }
  13. func playSong(named name: String) throws {
  14. // play song or throw an error if unavailable (曲を再生するか利用可能でないならばエラーをスローする)
  15. }
  16. }

Here’s how it’s imported by Objective-C:
ここにそれがObjective-Cによってインポートされる方法があります:

  1. @interface Jukebox : NSObject
  2. @property (nonatomic, strong, nonnull) NSSet<NSString *> *library;
  3. @property (nonatomic, copy, nullable) NSString *nowPlaying;
  4. @property (nonatomic, readonly, getter=isCurrentlyPlaying) BOOL currentlyPlaying;
  5. @property (nonatomic, class, readonly, nonnull) NSArray<NSString *> *favoritesPlaylist;
  6. - (nonnull instancetype)initWithSongs:(NSArray<NSString *> * __nonnull)songs OBJC_DESIGNATED_INITIALIZER;
  7. - (BOOL)playSong:(NSString * __nonnull)name error:(NSError * __nullable * __null_unspecified)error;
  8. @end

Configuring Swift Interfaces in Objective-C
スウィフトインターフェイスをObjective-Cにおいて構成する

In some cases, you need finer grained control over how your Swift API is exposed to Objective-C. You can use the @objc(name) attribute to change the name of a class, property, method, enumeration type, or enumeration case declaration in your interface as it’s exposed to Objective-C code.
いくつかの場合に、あなたはよりきめ細かな管理をあなたのスウィフト APIがObjective-Cに露出される方法に対して必要とします。あなたは、@objc(name)属性を使うことで、あなたのインターフェイスにおいてクラス、プロパティ、メソッド、列挙型、または列挙ケース宣言の名前を変更することがそれがObjective-Cコードに露出されるときに可能です。

For example, if the name of your Swift class contains a character that isn’t supported by Objective-C, you can provide an alternative name to use in Objective-C. If you provide an Objective-C name for a Swift function, use Objective-C selector syntax. Remember to add a colon (:) wherever a parameter follows a selector piece.
例えば、あなたのスウィフトクラスの名前がObjective-Cで支持されない文字を含むならば、あなたはObjective-Cで使うために代わりの名前を提供することができます。あなたがあるObjective-C名をスウィフト関数のために用意する場合は、Objective-Cセレクタ構文を使ってください。あるセレクタ片にパラメータが続くところはどこにでも、コロン(:)を加えるのを忘れないでください。

  1. @objc(Color)
  2. enum Цвет: Int {
  3. @objc(Red)
  4. case Красный
  5. @objc(Black)
  6. case Черный
  7. }
  8. @objc(Squirrel)
  9. class Белка: NSObject {
  10. @objc(color)
  11. var цвет: Цвет = .Красный
  12. @objc(initWithName:)
  13. init (имя: String) {
  14. // ...
  15. }
  16. @objc(hideNuts:inTree:)
  17. func прячьОрехи(количество: Int, вДереве дерево: Дерево) {
  18. // ...
  19. }
  20. }

When you use the @objc(name) attribute on a Swift class, the class is made available in Objective-C without any namespacing. As a result, this attribute can also be useful when migrating an archivable Objective-C class to Swift. Because archived objects store the name of their class in the archive, you should use the @objc(name) attribute to specify the same name as your Objective-C class so that older archives can be unarchived by your new Swift class.
あなたがスウィフトクラス上で@objc(name)属性を使うとき、そのクラスは何ら名前空間操作なしにObjective-Cで利用できるようにされます。その結果、この属性はまた、アーカイブできるObjective-Cクラスをスウィフトに移行するとき便利でありえます。アーカイブされたオブジェクトがそれらのクラスの名前をアーカイブに格納するので、あなたは@objc(name)属性を使ってあなたのObjective-Cクラスと同じ名前を指定しなければなりません、それでちょっと古くなったアーカイブがあなたの新しいスウィフトクラスによってアンアーカイブされることができます。

Requiring Dynamic Dispatch
動的なディスパッチを要求する

Swift APIs that are callable from Objective-C must be available through dynamic dispatch. However, the availability of dynamic dispatch doesn’t prevent the Swift compiler from selecting a more efficient dispatch approach when those APIs are called from Swift code.
Objective-Cから呼び出し可能なスウィフトAPIは、動的ディスパッチを通して利用可能でなければなりません。しかしながら、動的ディスパッチの利用可能性は、それらのAPIがスウィフトコードから呼び出される時に、スウィフトコンパイラがもっと効果的なディスパッチ取り組みを選択することを妨げはしません。

You use the @objc attribute along with the dynamic modifier to require that access to members be dynamically dispatched through the Objective-C runtime. Requiring this kind of dynamic dispatch is rarely necessary. However, it is necessary when using APIs like key–value observing or the method_exchangeImplementations function in the Objective-C runtime, which dynamically replace the implementation of a method at runtime.
あなたは、@objc属性に加えてdynamic修飾子を使うことで、メンバへのアクセスがObjective-Cランタイムを通して動的にディスパッチされることを要請します。この種の動的なディスパッチの要請は、めったに必要ではありません。しかしながら、それが必要であるのは、キー値監視またはmethod_exchangeImplementations関数のようなAPIをObjective-Cランタイムにおいて使う時です、それはあるメソッドの実装を実行時に動的に置き換えます。

Declarations marked with the dynamic modifier must also be explicitly marked with the @objc attribute unless the @objc attribute is implicitly added by the declaration’s context. For information about when the @objc attribute is implicitly added, see Declaration Attributes in The Swift Programming Language (Swift 4.1).
dynamic修飾子で印される宣言はまた、明示的に@objc属性で印されなければなりません、@objc属性が暗黙的にその宣言の持つ文脈によって加えられるのでない限り。@objc属性が暗黙的に加えられる場合についての情報として、宣言属性スウィフトプログラミング言語(Swift 4.1)で見てください。

Selectors
セレクタ

In Objective-C, a selector is a type that refers to the name of an Objective-C method. In Swift, Objective-C selectors are represented by the Selector structure, and can be constructed using the #selector expression. To create a selector for a method that can be called from Objective-C, pass the name of the method, such as #selector(MyViewController.tappedButton(_:)). To construct a selector for a property’s Objective-C getter or setter method, pass the property name prefixed by the getter: or setter: label, such as #selector(getter: MyViewController.myButton).
Ojbective-Cでは、セレクタはObjective-Cメソッドの名前を参照するある型です。スウィフトでは、Objective-CセレクタはSelector構造体によって表されます、そして#selector式を使って組み立てられることができます。Objective-Cから呼び出されることができるメソッドに対してセレクタを作成するには、そのメソッドの名前を渡してください、例えば#selector(MyViewController.tappedButton(_:))のように。あるプロパティの持つObjective-Cゲッターまたはセッターメソッドに対してセレクタを組み立てるには、getter:またはsetter:接頭辞を付けられたプロパティ名を渡してください、例えば#selector(getter: MyViewController.myButton)のように。

  1. import UIKit
  2. class MyViewController: UIViewController {
  3. let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))
  4. override init(nibName nibNameOrNil: NSNib.Name?, bundle nibBundleOrNil: Bundle?) {
  5. super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
  6. let action = #selector(MyViewController.tappedButton)
  7. myButton.addTarget(self, action: action, forControlEvents: .touchUpInside)
  8. }
  9. @objc func tappedButton(_ sender: UIButton?) {
  10. print("tapped button")
  11. }
  12. required init?(coder: NSCoder) {
  13. super.init(coder: coder)
  14. }
  15. }

Unsafe Invocation of Objective-C Methods
Objective-Cメソッドの安全でない発動

You can invoke an Objective-C method on an Objective-C compatible object using a selector with the perform(_:) method or one of its variants. Invoking a method using a selector is inherently unsafe, because the compiler cannot make any guarantees about the result, or even guarantee whether the object responds to the selector. Therefore, using these APIs is strongly discouraged unless your code specifically relies on the dynamic method resolution provided by the Objective-C runtime. For example, using these APIs would be appropriate if you need to implement a class that uses the target-action design pattern in its interface, like NSResponder does. In most cases, it’s safer and more convenient to cast the object to AnyObject and use optional chaining with a method call as described in id Compatibility.
あなたはObjective-CメソッドをObjective-C互換オブジェクト上で発動することがperform(_:)メソッドやそれの変種の1つを持つセレクタを使うことで可能です。メソッドをセレクタを使って発動することは、本質的に安全ではありません、なぜならコンパイラはその結果についてどんな保証も、またはオブジェクトがセレクタに応答するかどうかの保証さえもすることが不可能だからです。それゆえに、これらのAPIを使うことは強く反対されます、あなたのコードがObjective-Cランタイムによって提供される動的メソッド解決を特別に当てにするのでない限りは。例えば、これらのAPIの使用は、もしあなたがそれのインターフェイスにおいてターゲット-アクション・デザインパターンを使うクラスを実装する必要があるならば適切でしょう、NSResponderがするように。ほとんどの場合には、より安全でいっそう便利なのはそのオブジェクトをAnyObjectにキャストして、メソッド呼び出しとともにオプショナル連鎖を使うことです、id互換性で記述されるように。

The methods that perform a selector synchronously, such as perform(_:), return an implicitly unwrapped optional unmanaged pointer to an AnyObject instance (Unmanaged<AnyObject>!), because the type and ownership of the value returned by performing the selector can’t be determined at compile time. In contrast, the methods that perform a selector on a specific thread or after a delay, such as perform(_:on:with:waitUntilDone:modes:) and perform(_:with:afterDelay:), don’t return a value. See Unmanaged Objects for more information.
セレクタを同期的に実行するメソッド、例えばperform(_:)は、AnyObjectインスタンス(Unmanaged<AnyObject>!)に対する暗黙的にアンラップされたオプショナルの非管理ボインタを返します、なぜならセレクタ実行によって返される値の型と所有権はコンパイル時に確定されることができないからです。対照的に、セレクタを特定のスレッド上やある猶予の後で実行するメソッド、例えばperform(_:on:with:waitUntilDone:modes:)そしてperform(_:with:afterDelay:)は、値を返しません。更なる情報として管理されないオブジェクトを見てください。

  1. let string: NSString = "Hello, Cocoa!"
  2. let selector = #selector(NSString.lowercased(with:))
  3. let locale = Locale.current
  4. if let result = string.perform(selector, with: locale) {
  5. print(result.takeUnretainedValue())
  6. }
  7. // Prints "hello, cocoa!"

Attempting to invoke a method on an object with an unrecognized selector causes the receiver to call doesNotRecognizeSelector(_:), which by default raises an NSInvalidArgumentException exception.
メソッドをオブジェクト上で十分に評価されていないセレクタで発動することは、そのレシーバがdoesNotRecognizeSelector(_:)を呼び出す原因になります、それは初期設定ではNSInvalidArgumentException例外を引き起こします。

  1. let array: NSArray = ["delta", "alpha", "zulu"]
  2. // Not a compile-time error because NSDictionary has this selector. (コンパイル時エラーでは無い、なぜならNSDictionaryはこのセレクタを持つからです。)
  3. let selector = #selector(NSDictionary.allKeysForObject)
  4. // Raises an exception because NSArray does not respond to this selector. (例外を引き起こします、なぜならNSArrayはこのセレクタに応答しないからです。)
  5. array.perform(selector)

Keys and Key Paths
キーとキーパス

In Objective-C, a key is a string that identifies a specific property of an object. A key path is a string of dot-separated keys that specifies a sequence of object properties to traverse. Keys and key paths are frequently used for key-value coding (KVC), a mechanism for indirectly accessing an object’s attributes and relationships using string identifiers. Keys and key paths are also used for key-value observing (KVO), a mechanism that enables an object to be notified directly when a property of another object changes.
Objective-Cでは、keyはオプジェクトの特定のプロパティを識別するある文字列です。キーパスは、ドットで区切られたいくらかのキーからなる文字列で、巡回していく一連のオブジェクトプロパティを指定するものです。キーとキーパスは、文字列識別子を使ってオブジェクトの属性および関連付け(リレーションシップ)に間接的にアクセスするための仕組み、キー値コーディング(KVC)のためにしばしば使われます。キーとキーパスはまた、他のオブジェクトのプロパティが変化した時にあるオブジェクトが直接に通知されることを可能にする仕組み、キー値監視(KVO)のためにも使われます。

In Swift, you can use a key-path expression to create key paths for accessing properties. For example, you can use the \Animal.name key-path expression to access the name property of the Animal class shown below. Key paths created using key-path expressions include type information about the properties they reference. Applying a key path to an instance results in a value of the same type as accessing that instance’s property directly. A key-path expression accepts property references and chained property references, such as \Animal.name.count.
スウィフトでは、あなたはキーパス式を使うことで、プロパティにアクセスするためのキーパスを作成できます。例えば、あなたは\Animal.nameキーパス式を使って、下で示すAnimalクラスのnameプロパティにアクセスできます。キーパス式を使って作成されるキーパスは、それらが参照するプロパティについての型情報を含みます。キーパス式をインスタンスに適用することは、そのインスタンスの持つプロパティに直接にアクセスするのと同じ型の値という結果になります。キーパス式は、プロパティ参照そして数珠つなぎにされたプロパティ参照を受け入れます、例えば\Animal.name.countのように。

  1. class Animal: NSObject {
  2. @objc var name: String
  3. init(name: String) {
  4. self.name = name
  5. }
  6. }
  7. let llama = Animal(name: "Llama")
  8. let nameAccessor = \Animal.name
  9. let nameCountAccessor = \Animal.name.count
  10. llama[keyPath: nameAccessor]
  11. // "Llama"
  12. llama[keyPath: nameCountAccessor]
  13. // "5"

In Swift, you can also use the #keyPath string expression to create compiler-checked keys and key paths that can be used by KVC methods like value(forKey:) and value(forKeyPath:), and KVO methods like addObserver(_:forKeyPath:options:context:). The #keyPath string expression accepts chained method or property references. It also supports chaining through optional values within a chain, such as #keyPath(Person.bestFriend.name). Unlike key paths created using key-path expressions, key paths created using the #keyPath string expression don’t pass type information about the properties or methods they reference to the APIs that accept key paths.
スウィフトでは、あなたは#keyPath文字列式を使うことでコンパイラチェック済みのキーやキーパスを作成できます、それらはvalue(forKey:)value(forKeyPath:)のようなKVCメソッドおよびaddObserver(_:forKeyPath:options:context:)のようなKVOメソッドによって使われることができます。#keyPath文字列式は、数珠つなぎにされたメソッドまたはプロパティ参照を受け入れます。それはまた、ある数珠つなぎ内でオプショナル値を通した連鎖をサポートします、例えば#keyPath(Person.bestFriend.name)など。キーパス式を使って作成されるキーパスと違い、#keyPath文字列式を使って作成されるキーパスは、それらが参照するプロパティやメソッドについての型情報をキーパスを受け入れるAPIへ伝えません。

  1. class Person: NSObject {
  2. @objc var name: String
  3. @objc var friends: [Person] = []
  4. @objc var bestFriend: Person? = nil
  5. init(name: String) {
  6. self.name = name
  7. }
  8. }
  9. let gabrielle = Person(name: "Gabrielle")
  10. let jim = Person(name: "Jim")
  11. let yuanyuan = Person(name: "Yuanyuan")
  12. gabrielle.friends = [jim, yuanyuan]
  13. gabrielle.bestFriend = yuanyuan
  14. #keyPath(Person.name)
  15. // "name"
  16. gabrielle.value(forKey: #keyPath(Person.name))
  17. // "Gabrielle"
  18. #keyPath(Person.bestFriend.name)
  19. // "bestFriend.name"
  20. gabrielle.value(forKeyPath: #keyPath(Person.bestFriend.name))
  21. // "Yuanyuan"
  22. #keyPath(Person.friends.name)
  23. // "friends.name"
  24. gabrielle.value(forKeyPath: #keyPath(Person.friends.name))
  25. // ["Yuanyuan", "Jim"]