ProgrammingiOS開発者

Swiftにおけるprivate/protected/internal/public/openのアクセスの仕組みを説明してください。各修飾子を使用するのに最適なタイミングと、実際のプロジェクトで直面する可能性のあるエラーは何ですか?

Hintsage AIアシスタントで面接を突破

回答

Swiftには、型のメンバー(プロパティ、メソッドなど)および型自体へのアクセスレベルが5つあります。

  • open — 最大の公開度。モジュールの外部でも継承およびオーバーライドできます。
  • public — モジュールの外部で利用可能ですが、オーバーライド/継承はできません。
  • internal(デフォルト) — モジュール内で利用可能。
  • fileprivate — ファイル内のみにアクセス可能。
  • private — 宣言のスコープ内のみにアクセス可能(extensionもこのスコープ内)。

使用ルール:

  • privateは、宣言の外に見えるべきでないロジックに使用します。
  • fileprivateは、同じファイル内でデータを交換する必要がある場合に使用します(たとえば、2つの関連するextension間)。
  • internal — モジュール内で一般公開されるもののデフォルト。
  • public/open — 他のモジュールやフレームワークで使用されるAPI用。

例:

open class MyOpenClass {} public class MyPublicClass {} intern class InternalClass {} fileprivate class FilePrivateClass {} private class PrivateClass {}

深い質問

openはpublicとクラスの定義においてどう違いますか?なぜすべてのpublicクラスが継承に使用できないのですか?

回答: openは、モジュールの外からオーバーライドおよび継承できるクラス/メソッドにマークします。publicは使用へのアクセスを開きますが、モジュールの外で継承することは許可されません。一方では、実装を望ましくない変更から保護し、他方では必要な拡張ポイントのみを開放します。

public class PublicClass {} open class OpenClass {} // 別のモジュールで: class InheritFromOpen: OpenClass {} // OK class InheritFromPublic: PublicClass {} // エラー!

トピックの微妙さから発生する実際のエラーの例


逸話

あるライブラリでクラスがpublicとしてマークされていて、外部プロジェクトがそれを拡張しようとし、メソッドをオーバーライドしました。プロジェクトはpublicとopenの違いを誤解していたためにコンパイルできず、チームはインターフェースの再設計に余分な1週間を費やしました。


逸話

1つのファイル内で、extensionからprivateプロパティにアクセスしようとしたが、そのプロパティはfileprivateとしてではなく、privateとして宣言されていました。これにより、統合ビルドでのみ見つかったコンパイラエラーが発生しました。


逸話

複数のフレームワークを持つアプリケーションで、すべての型はinternal(デフォルト)としてマークされていました。モジュール間で型を使用する必要が生じたとき、インターフェースが利用できず、publicへの再宣言に十数個の修正が必要で、追加の時間とテストがかかりました。