7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

NSObjectについてちょっと深堀りしてみた

Posted at

概要

普段何気なく使用しているNSObjectについて、改めて調べまとめました。

なお、筆者はSwift、Objective-C及びアプリ開発初心者のため、内容の正確性をしっかり保証することができません。もし、不正確な表現などございましたら、コメントいただけると幸いです。

NSObjectとは

Cocoaフレームワークにおける数少ないルートクラスで、NSObjectを継承することで、動的型付けであるObj-Cランタイムの柔軟性を教授することができます。

その柔軟性とは?

メソッド呼び出しをランタイム時に動的に行えます。

より詳細には、NSObjectを継承するサブクラスのメソッド呼び出し時には objc_msgSend()によるインターセプションを介するため、ランタイム時にメソッド呼び出し先を柔軟に変えること(通称Swizzling)などが可能になります。

たとえば以下の一行目のようなコードはコンパイラによって、 objc_msgSendの呼び出しに置き換えられます。

[obj message];
// 👇こうなる
objc_msgSend(obj, @selector(message));

ただし、こうした柔軟性はObj-Cが動的型付け言語故行えることであり、Swiftランタイムではコンパイル時に静的に型が決まる必要があるため、こういった柔軟で動的な挙動を得るためにはNSObject、すなわちObj-Cランタイムの力を借りる必要が出てきます。

例えば、我々がよく使うIBOutletなどのKeyValueコーディングはまさにこの機能を使用していることになります。(UIViewはNSObjectですしおすし)SwiftはObj-Cランタイムという巨人の方に乗っかっていると言えますね。

NSObjectを継承しないクラスについて

では、NSObjectを継承していないクラスの場合はどうなんでしょうか?

結論、NSObjectと継承しないSwift上のクラスは、 メソッド呼び出し時に前述の objc_msgSend()を介しません。

ただし、NSObjectを継承していなくても、そのクラスはObj-Cクラスであり、NSObjectとの互換性を持った一部の関数の実装のみ行っているようです。また、Obj-Cランタイムメタデータもランタイム側から提供されないようです。

動的なメソッド呼び出しに関連する@objcとdynamicについて

@objcはSwift上の実装をObj-Cから参照できるようにする

Obj-C上からSwiftで書かれたクラスのメソッドやプロパティにアクセスするためには @objcアトリビュートが必要になります。#selectorで呼び出す場合、必ず呼び出し先に @objcを付けることになりますが、これもObj-Cランタイムの動的なメソッド呼び出しを活用するためです。

dynamicが付いた関数やプロパティの呼び出しには、Dynamic dispatchを使用することをコンパイラに知らせる

Apply this modifier to any member of a class that can be represented by Objective-C. When you mark a member declaration with the dynamic modifier, access to that member is always dynamically dispatched using the Objective-C runtime. Access to that member is never inlined or devirtualized by the compiler.

Because declarations marked with the dynamic modifier are dispatched using the Objective-C runtime, they must be marked with the objc attribute.

https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#//apple_ref/swift/grammar/declaration-modifiers

dynamicキーワードを付けることで、その関数やプロパティへのアクセスは、必ずDinamyc Dispatchを介することになります。そのため、パフォーマンスの観点で悪影響があることから、使用時にはそういった観点を持ったほうが良いかも知れません。

参考リンク

What is NSObject? When do Swift developers need to use NSObject?

To the depth of @objc and dynamic in Swift

What Does the Dynamic Keyword Mean in Swift 3

mikeash.com: Friday Q&A 2012-11-16: Let's Build objc_msgSend

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?