0

ARCに問題があります。数時間のデバッグの後、私はあきらめてここにチェックすることにしました。ARCがインスタンス変数を解放しない

基本的に私はMainViewControllerを持っていて、PreviewsViewのインスタンスを作成しています。 PreviewsView

私は、デリゲートとデータソースのプロパティがあります。

@property (nonatomic, unsafe_unretained) IBOutlet id<PreviewsDataSource> dataSource; 
@property (nonatomic, unsafe_unretained) IBOutlet id<PreviewsDelegate> delegate; 

私は、MainViewControllerPreviewsViewのインスタンスを作成して表示し、インスタンス変数として保存するためにそれを追加し、delegatedataSourceとしてselfを設定します。

- (void)addPreviews { 
    previewsView = [[PreviewsView alloc] initWithFrame:CGRectMake(0, 75, 1024, 480)]; 
    previewsView.dataSource = self; 
    previewsView.delegate = self; 
    [self.view addSubview:previewsView]; 
} 

ナビゲーションコントローラーからMainViewControllerを削除すると、割り当てが無効になりますが、previewsViewはまだ存在します(W HY?)を呼び出し、実際に[self.delegate doSomeStuff]をトリガするメソッドを実行します。 MainViewControllerはすでに割り当てを解除しています - EXC_BAD_ACCESSをスローします。したがって、基本的

  • MainViewControllerのインスタンスPreviewsViewのインスタンスを所有している(previewsView)MainViewControllerの解除インスタンス後
  • PreviewsViewdelegatedataSourceとして割り当てられMainViewController
  • インスタンスは、previewsViewがまだ生きているとランニング。

おかげさまで

+1

'(addPreviews'メソッドで)' previewsView'という名前のビューを作成するが、完全に異なるサブビュー( 'previewsCaroucel')を追加することは意図的ですか? – omz

+0

申し訳ありませんが、ここに投稿する前に変数の名前を変更しています – OgreSwamp

答えて

1

unsafe_unretainedはivarを付けません。 __weakは行います。

MainViewControllerメンバーpreviewsViewはそれを保持しますか? viewDidUnloadでは、またはpreviewsViewを終了した後、それをnilに設定します。つまり、previewsView = nilです。

一般に、ivarsとして保持されているすべてのIBOutletsまたはサブビューは__weakである必要があります。あなたがサブビューとして追加した後にpreviewsViewを必要としない場合は、ivarを削除することができます。

希望すると便利です。

+0

AFAIK「弱い」はiOS 4.xでは利用できないため、私にとって解決策ではありません。 – OgreSwamp

+1

そのため、明示的にメンバーを退室させたり、保持したりしないでください。 –

+0

この場合、nilはどのように役立ちますか? NilはpreviewsViewを解放しません、previewsViewはまだリリースされたMainViewControllerへの参照を持ちます。 – OgreSwamp

2

MainViewControllerをリリースする前に、デリゲートをnilに設定する必要があります。 previewsView.delegate = nil; previewsView.dataSource = nil;

好ましい呼び出しあなたのdeallocメソッドでこのコードMainViewController - >あなたはまだのようにARCにもそれを使用することができ、この

- (void) dealloc 
{ 
    previewsView.dataSource = nil; 
    previewsView.delegate = nil; 
    [super dealloc]; 
} 
あなたはプロトコルが想定しているということを覚えておいてください

! previewsViewのインスタンスはまだ「生きています」(通知は同じ方法で動作します)、死んでいるかどうかにかかわらずインスタンスにメッセージを送信しようとします。したがって、MainViewControllerがリエレースされると、previewsViewも呼び出されますが、デリゲートはまだ "生きています"。したがって、あなたはそれらをunilに設定することによってそれらのundelegateする必要があります;)

関連する問題