2013-12-18 3 views
9
-(void) scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    PO(NSStringFromCGPoint(self.tableView.contentOffset)); 
    PO(NSStringFromUIEdgeInsets(self.tableView.contentInset)); 

    while(false); 
} 

-(void)dealloc 
{ 
    PO(NSStringFromClass([self class])); 
    PO(@"Deallocated"); 
    self.tableView.delegate=nil; 
} 

ここで、エラーを避けるためにself.tableView.delegate = nilを設定する必要があります。オブジェクトがとにかく破棄される場合、deallocでdelegateをnilに設定するのはなぜですか?

以前の質問から、デリゲートが破棄されたときにself.tableView.delegateが自動的に無効にならないことは承知しています。これは、代理人のタイプが弱参照の代わりに参照を割り当てるためです。

しかし、self.tableViewについてはどうですか?

self.tableViewを強く参照する唯一のことは、selfとself itsefが所有するsuperviewです。

したがって、selfが破壊されると、self.tableViewも破壊されるはずです。つまり、self.tableView.delegateもなくなります。

なぜ、私はself.tableView.delegate=nilを設定する必要がありますか。

答えて

5

唯一のself.tableViewへの参照を保持している場合は、デリゲートをnilに設定する必要はありません。

デリゲートをnilに設定する必要がある唯一の状況は、別のクラスがクラスをデリゲートとして持つ場合です。クラスが破棄された場合、他のクラスはクラスを検索してメソッドを実装します。コールはそこにはありません。

-1

実際これは必須ではありません。保持サイクルの形成を避けるため、これを行っています。我々は、強力な参照を持つ代理人を作成すべきではありません。誤って強力な参照を持つデリゲートを作成した場合は、親と子の両方が解放されません。その場合、dealloc自体は呼び出されません。だから、それは必要ではない。

9

多くの場合、delegateをnilに設定する必要があります。あなたのケースでは、tableViewはいくつかの外部クラスによって参照される可能性があり、クラスdeallocメソッドの後には破棄されません。また、デリゲートメソッドをクラッシュさせ続けることになります。 別のスレッド(NSURLConnectionなど)で動作するクラスがいくつかあります。たとえそれを解放しても、それは別のスレッドに保持されているため、デリゲートメソッドを引き続き呼び出すことができます。

0

は、我々はあなたがgesture recognizerを持っていて、そのdelegateを設定SpriteKitベースsceneを考えてみましょう。

次にdeallocこのsceneとそのrecognizercontrollerからです。

このプロセス中にscenedelegateメソッドが呼び出された場合は、クラッシュになります。

関連する問題