1

私が書いているペット アプリケーションでは、メイン ウィンドウにいくつかのカスタム ビューが配置されており、それぞれにラベル、コンボボックス、ボタンがあります。

ボタンをクリックすると、同じビューでコンボボックスを見つけるコードが呼び出され、次の関数 ( のクラス メソッドRVListEditorController)が呼び出されます。

+ (void) editComboBox: (NSComboBox *) aComboBox
{
    // Analyze says "possible leak", but both methods ending the panel will release the controller.

    RVListEditorController *controller = [[RVListEditorController alloc] initWithComboBox: aComboBox];

    [NSApp beginSheet: [controller window]
       modalForWindow: [aComboBox window]
        modalDelegate: controller
       didEndSelector: NULL
          contextInfo: nil];
}

このコードは のインスタンスを作成しますRVListEditorController。これは、コンボボックスのリストを編集できるパネルを制御します (アイテムの削除、アイテムの並べ替えなど)。他のコントロールの中でも、閉じるための 2 つのボタンがあります。[キャンセル] と [OK] です。

2 つのボタンのコードは次のとおりです。

- (IBAction) closeSheetWithOK: (id) sender
{
    [NSApp endSheet: editingPanel];
    [editingPanel orderOut: self];
    [comboBoxValues setArray: valuesCopy];
    if (comboBoxValues.count > 0)
        [editedComboBox setStringValue: [comboBoxValues objectAtIndex: 0]];
    [self release];
}


- (IBAction) closeSheetWithCancel: (id) sender
{
    [NSApp endSheet: editingPanel];
    [editingPanel orderOut: self];
    [self release];
}

これらは、シートを閉じる 2 つのボタンのみです。私の質問は、インスタンスの有効期間管理についてです。これはクラス メソッドで割り当てられますが、制御は再び Cocoa に渡され、クラス メソッドは終了します。インスタンスを解放するために見つけた唯一の場所は、閉じるボタンの 2 つのハンドラーです。私の問題は、beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo:単にシートを開いてから再び閉じるまで待って、閉じた方法の値を返すことではありません。その場合は、クラス メソッドでインスタンスを閉じることができ、気分が良くなります。

私の質問: インスタンスの有効期間を処理するためのより良い方法はありますか、それともシート ウィンドウをモーダルに開き、再び閉じるのを待つことができる Cocoa の何かがあるので、すぐにインスタンスを解放することができます。それ?何も思い浮かびませんが、結局のところ、私は比較的初心者です。

FWIW、コードは機能するので、エラーはありません。クラス メソッドに何かを割り当ててから、それ自体の 2 つのインスタンス メソッドで解放する必要があるという構造には、単純に満足できません。

4

3 に答える 3

2

クラスメソッドであってはならないもののように見えます。そのライフサイクルを定義する際の問題は、明確な所有権なしに作成されているという警告サインです。

于 2011-07-22T19:15:46.340 に答える
1

クラス メソッドに何かを割り当ててから、それ自体の 2 つのインスタンス メソッドで解放する必要があるという構造には、単純に満足できません。

それには一定の論理がありますが、ウィンドウモーダルシートはインスタンスメソッドによってより自然に開始されるとも主張します。ウィンドウは、単なるクラスではなく、なんらかのオブジェクトの表現です。

ただし、ライフサイクルに関するより一般的な質問には答えていません。

于 2011-07-22T19:15:29.947 に答える
1

私は満足のいくものを手に入れることができました。beginSheet: を提供し、シートが終了した後に呼び出されるメソッドを使用して、コントローラーにコンテキスト情報を提供しました。IOW:

    [NSApp beginSheet: [controller window]
       modalForWindow: [aComboBox window]
        modalDelegate: controller
       didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo)
          contextInfo: (void *)controller];
}

2 つのボタンのコードは次のようになります。

- (IBAction) closeSheetWithOK: (id) sender
{
    [comboBoxValues setArray: valuesCopy];
    if (comboBoxValues.count > 0)
        [editedComboBox setStringValue: [comboBoxValues objectAtIndex: 0]];
    [NSApp endSheet: editingPanel];
}


- (IBAction) closeSheetWithCancel: (id) sender
{
    [NSApp endSheet: editingPanel];
}

コードsheetDidEnd:returnCode:contextInfo:は次のとおりです。

- (void) sheetDidEnd: (NSWindow *) sheet returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo
{
    [sheet orderOut: (id)contextInfo];
    [(id)contextInfo release];
}

つまり、IMO、このような状況でできる最善のことです。これがウィンドウ コントローラのインスタンス メソッド AFAICT から呼び出された場合、手順は同じでした。

于 2011-07-22T22:03:29.203 に答える