2016-09-14 4 views
2

は、次のような共通の単純な型消去スキームタイプ消去:タイプ情報を消去するときに、消去されたタイプのインスタンスの保存されたデータへのアクセスを不可逆的に失う危険がありますか?

protocol Foo { 
    associatedtype Bar 
    func bar() -> Bar 
} 

struct AnyFoo<Bar>: Foo { 
    private let _bar:() -> Bar 

    init<F: Foo>(_ foo: F) where F.Bar == Bar { 
     _bar = foo.bar 
      /* stores a reference to foo.bar, 
       so foo kept alive by ARC? */ 
    } 

    func bar() -> Bar { 
     return _bar() 
    } 
} 

たちが出てスライスにのみ興味そこから、「大」タイプの一時的なインスタンス初期化子引数上記fooは(あることを意図し)されたと考えてみましょうFoo(すなわち、bar()メソッド)によって青写真された情報。

struct Huge { /* ... */ } 

struct Foobar: Foo { 
    internal func bar() -> String { 
     return "foo" 
    } 
    let lotsOfData: Huge = Huge() 
} 

func getAnyFooStr() -> AnyFoo<String> { 
    let foobar = Foobar() 
    return AnyFoo(foobar) 
} 

let anyStrFoo = getAnyFooStr() 
    /* we can now access anyStrFoo.bar() (-> "foo") from our 
     erased type, but do lotsOfData of the underlying seemingly 
     temporary Foobar() instance still "live", unreachable? */ 
  • Q:我々はまだによる閉鎖が参照型であるという事実にメモリに生きていると到達不能fooの残りのコンテンツを続けるのだろうか?もしそうなら、私はこの失われた、しかし生きているコンテンツへのアクセスを再利用することはできないと思いますか?

(私は、(a)はdeinitコールの不足が、私はそんなに私はこのためにいくつかの非自己検証を必要とする最後の時間を自分自身を混同してきたのモニタリング、クラスとしてFoobarで上記を試してみました特に)Foobarが値型である場合の


のXcode 8.0 /スウィフト3.

+1

'Foobar'はすぐanyStrFoo'がスコープの外に出る'としてリリースされなければなりません。あなたはクラスによって '巨大な'をdeinitメソッドに置き換えることによってそれを確認することができます。 –

+0

@MartinRしかし、 'AnyFoo'インスタンスがスコープ内にある限り、' Foobar'インスタンスは解放されません(到達不可能なデータで)? Ninja-edit:また、 'anyStrFoo'が' Foobar'インスタンスのスコープから外れたとき(そしてその 'Huge'メンバーのインスタンスで)、解放されたとき、感謝します。 – dfri

+2

ここには本当の問題はありません。インスタンスにバインドされた 'bar'メソッドである' let fb = Foobar()。bar'を指定した場合(これが正しい用語であるかどうかはわかりません)も同じことが起こります。 'fb'が生存している限り、値は生きています。クロージャーはインスタンスを必要とするかもしれないので、何が起こるはずですか? –

答えて

2

はい、それは閉鎖型消去とは何の関係も:) を持っていませんは、クロージャが有効である限り、バインドされているインスタンスを (すべてのプロパティを持つ)のままにします。ここで

は簡単な例です:

class Huge { 
    deinit { print("deinit Huge") } 
} 

struct Foobar { 
    internal func bar() -> String { 
     return "foo" 
    } 
    let lotsOfData: Huge = Huge() 
} 

do { 
    let fb = Foobar().bar // the type of `fb` is `() -> String` 
    print("still alive ...") 
} 
print("... out of scope now") 

出力:

 
still alive ... 
deinit Huge 
... out of scope now 
関連する問題