0

通常、xib からカスタム ビューをロードするコードは次のようになります。

@implemenation MyCustomView

- (id)init
{
    [self release];

    if ((self = [[NSBundle loadViewFromXibName:@"MyCustomView" withClass:[MyCustomView class] owner:nil] retain]))
    {
        //some init here
    }

    return self;
}

where [NSBundle loadViewFromXibName:withClass:owner:]- xib からロードされた atoreleased ビューを返します。

そして、すべて正常に動作しています。しかし、ARC と同等のコードで書き込もうとすると、次のようになります。

@implemenation MyCustomView

- (id)init
{
    if ((self = [NSBundle loadViewFromXibName:@"MyCustomView" withClass:[MyCustomView class] owner:nil]))
    {
        //some init here
    }

    return self;
}

EX_BAD_ACCESS でアプリがクラッシュする (解放メッセージが割り当て解除されたインスタンスに送信される) この場合はどうなりますか? そして、どうすればこの問題を解決できますか?

更新この問題は、iOS6 SDK (iOS6 シミュレーター) でのみ発生します。iOS5 SDK および iOS 5 デバイス/シミュレーターでは、すべて問題ありません。

更新この問題は、テーブル ビューのライフサイクルで割り当てが解除されたテーブル ビュー セルでのみ発生します。スタティック セル ビルダー (xib からロードされたセルを返すもの) を実装し、内部セルの初期化を awakeFromNib に移動しました。現在、すべて正常に動作しています。

なぜこの問題が発生するのか理解できません - 「自己」は __strong であり、それに任意のオブジェクトを割り当てた場合、自動解放できません。私は間違っていますか?

4

2 に答える 2

-1

new以前はこのパターンを実行していましたが、ARCの後、代わりにオーバーライドして回避しようとしました。これが問題を引き起こす理由はわかりませんが、次の2つのうちの1つを推測しています。

  1. Cocoaの名前付けプレフィックスが[self release]ある場合、ARCは適切に処理します。nib(または他の場所)からロードした場合、同じ動作は得られませんself = [super init...]init
  2. selfからではないものを割り当てると、[super init...]で割り当てたメモリが失われます[MyCustomView alloc]

私はそれが後者だと思う傾向があります。nibからロードする場合は、newからではなく、などのファクトリメソッドでロードすることをお勧めしinitます。

編集:この問題がiOS 6にあると言ったとき、私は以前と同じ問題に遭遇していると確信しています。これをデバッグしたとき、ブレークポイントを中に入れましたdealloc。を呼び出すたびに、そこで停止することがわかりますinit

于 2012-11-26T08:34:31.387 に答える
-1

代わりにこれを使用してください:

NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"MyCustomClass" owner:nil options:nil];
self = [nibViews objectAtIndex: 0];

//理想的には、ここでその配列をループし、どのビューがクラスのメンバーであるかを確認して、それに自分自身を割り当てるとよいでしょう。

initメソッドで。

お役に立てれば。

乾杯!

于 2012-11-26T08:37:18.133 に答える