45318


  * [goktugyil/EZSwiftExtensions: How Swift standard types and classes were supposed to work.](https://github.com/goktugyil/EZSwiftExtensions)
  * [ReactiveX/RxSwift: Reactive Programming in Swift](https://github.com/ReactiveX/RxSwift)

上記のようなタイプのクラスにextensionでメソッドを生やすタイプのライブラリについてです。

一度、extensionで生えたメソッドは消せないため、一度コンパイルのタイミングのどこかでimportされるとimportしていないファイルでもその生えたメソッドにアクセスできると思います。これを防ぐことは可能でしょうか？

質問がフワついてしまいそうなので、まとめますと

  * メソッドを生やすタイプのライブラリはimportすると全ファイル（プロジェクト全体）に影響が出てしまう？（私は出てしまうと認識しており、念の為の確認です）
  * 出てしまう場合、防ぐ手立てはありますか？
  * 出てしまうのであれば、どこか一箇所でimportすればよいように思います。その適切な場所とはどこでしょうか？


CC BY-SA 4.0
2018-06-29T23:52:51.287
45175
2018-07-04T18:46:35.190
2018-06-30T00:08:09.137
19110
9008
question
swift swift3
クラスを拡張するタイプのライブラリはimportすると全プロジェクトファイルに影響がでると思います。現在これを防ぐ手立てはありますか？


### Extensionについて

懸念を検証するために次のようなfileprivateなextensionを作り、2つのViewControllerから生やしたメソッドにアクセスできるか検証してみました。

[code]

    fileprivate extension UIView {
        public func test() {
            print("test")
        }
    }
    
[/code]

結果  
FirstViewController(該当のExtensionを **記述した** ViewController)  
→ アクセスできました。  
SecondViewController(該当のExtensionを **記述していない** ViewController)  
→ アクセスできませんでした。

これはextensionのアクセスレベルがfileprivateであるために発生した現象です。  
extensionのアクセスレベルを通常のinternal(つまり何も記述しない)にしたところ、両ViewControllerで生やしたメソッドにアクセスできました。

### ライブラリについて

提示いただいたライブラリの1つであるRxSwiftに含まれるRxCocoaライブラリのソースコードの一部である _UIView+Rx.swift_
のソースコードを一部確認しました。  
次のような記述でした。

[code]

    extension Reactive where Base: UIView {
        /// Bindable sink for `hidden` property.
        public var isHidden: Binder<Bool> {
            return Binder(self.base) { view, hidden in
                view.isHidden = hidden
            }
        }
    ~~以降は省略~~~
    
[/code]

extensionでのアクセス制御はpublicとなっているため、Swiftのソースコード上のどこかでimportするとプロジェクト全体に影響が出るというのは、プロジェクト内部にTarget(いわゆるモジュール)が1つしか無い場合には間違いないと思います。

Targetが複数存在するプロジェクトの場合、自身が所属するTargetではない別Targetに属するクラス情報などを参照することができません(publicでアクセス制御を行っているものは別)。  
例としてA TargetではRxSwiftを利用していてimportもしている場合でも、B
Targetに属するソースコードではRxSwiftの存在を知らないということになります。  
このためA TargetでimportしたRXSwiftをB Targetでimportせず利用することはできません。

そのため、懸念いただいている点はExtensionの仕様によるもの、というより  
**Swiftという言語のアクセス制御の仕様によるもの**  
と考えるほうが正しい気がしています。


CC BY-SA 4.0
2018-07-04T18:46:35.190
45318
2018-07-04T18:46:35.190
26681
45175
answer