1

私のアプリケーションには、のサブクラスがありNSWindowControllerます。サブクラス- (void)awakeFromNibのインスタンスを作成して、一番下に配置されたボタンバーを作成します。NSView

self.buttonBar = [[CNButtonBar alloc] initWithSize:NSMakeSize(tableViewRect.size.width-1, 25)];

これCNButtonBarには、ボタンを追加する方法があります。私はそれを2つ作成します:

[buttonBar addButtonWithTitle:nil
                        image:[NSImage imageNamed:NSImageNameAddTemplate]
                       target:self
                       action:@selector(btnAccountAddAction:)
                    alignment:CNBarButtonAlignLeft];

[buttonBar addButtonWithTitle:nil
                        image:[NSImage imageNamed:NSImageNameRemoveTemplate]
                       target:self
                       action:@selector(btnAccountRemoveAction:)
                    alignment:CNBarButtonAlignLeft];

これらの2つのアクションメソッドはNSViewController、2つのメッセージを送信するのと同じインスタンスで定義されていaddButtonWithTitle:...ます。

アクションの設定に使用されるメソッドは、次のように定義されています。

- (void)btnAccountAddAction:(id)sender
{
    ....
}

- (void)btnAccountRemoveAction:(id)sender
{
    ....
}

しかし、それは機能しません。これらの2つのボタンのいずれかをクリックするたびに、アプリケーションがクラッシュし、次のような例外がスローされます。

-[__NSArrayM btnAccountAddAction:]: unrecognized selector sent to instance 0x1001454e0

この例外を調べたところ、絶対に正しいです。NSArray私が呼び出したいようなメソッドはありません。ただし、この例外をスローするオブジェクトは時々変更されます。オブジェクトがある場合もあれば、__NSDataオブジェクトがある場合もあります__NSDictionary。レシーバーは私のNSWindowControllerサブクラスではないようです。しかし、与えられたインスタンスID0x1001454e0は私NSWindowControllerが持っているものと同じです。

髪を引き裂きたくなる!ここで何が問題になっていますか...?ありがとう。


アップデート

CNButtonBarとは、両方ともCNButtonBarButton完全にコードによって描画されていると言わざるを得ません。の完全なメソッドaddButtonWithTitle:image:target:action:alignment:はここにあります(これはCNButtonBar、のサブクラスで発生します(代わりNSViewに使用する必要がありますか?)、のサブクラスです):NSViewControllerCNButtonBarButtonNSButton

- (void)addButtonWithTitle:(NSString*)title image:(NSImage*)image target:(id)target action:(SEL)action alignment:(CNBarButtonAlign)align
{
    if (self.buttons == nil)
        self.buttons = [[NSMutableArray alloc] init];

    CNButtonBarButton *button = [[CNButtonBarButton alloc] init];
    [self.buttons addObject:button];

    button.title = title;
    button.image = image;
    button.target = target;
    button.action = action;
    button.align = align;

    NSRect buttonRect;
    NSSize titleSize = NSMakeSize(0, 0);
    if (button.title.length > 0) {
        NSMutableParagraphStyle* textStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
        [textStyle setAlignment: NSCenterTextAlignment];

        NSColor *textColor = [[NSColor blackColor] colorWithAlphaComponent:0.9];
        NSShadow* textShadow = [[NSShadow alloc] init];
        [textShadow setShadowColor: [NSColor whiteColor]];
        [textShadow setShadowOffset: NSMakeSize(0, -1)];
        [textShadow setShadowBlurRadius: 0];

        button.titleTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                      [NSFont fontWithName:@"Helvetica Neue" size:11.0], NSFontAttributeName,
                                      textShadow,                     NSShadowAttributeName,
                                      textColor,                      NSForegroundColorAttributeName,
                                      textStyle,                      NSParagraphStyleAttributeName,
                                      nil];
        titleSize = [title sizeWithAttributes:button.titleTextAttributes];
        buttonRect = NSMakeRect(0, 0, roundf(titleSize.width) + kTextInset * 2, NSHeight(self.frame) - 1);

    }

    if (button.image != nil) {
        NSSize imageSize = [image size];
        if (button.title.length == 0) {
            buttonRect = NSMakeRect(0, 0, imageSize.width + kImageInset * 2, NSHeight(self.frame) - 1);

        } else {
            buttonRect = NSMakeRect(0, 0,
                                    (imageSize.width + kImageInset * 2) + (roundf(titleSize.width) + kTextInset),
                                    NSHeight(self.frame) - 1);
        }
    }

    switch (self.align) {
        case CNButtonBarAlignNormal: {
            switch (button.align) {
                case CNButtonBarButtonAlignLeft: {
                    button.frame = NSMakeRect(offsetLeft, 0, NSWidth(buttonRect), NSHeight(buttonRect));
                    offsetLeft += 1 * [self.buttons indexOfObject:button] + NSWidth(button.frame);
                    break;
                }

                case CNButtonBarButtonAlignRight: {
                    button.frame = NSMakeRect(offsetRight - NSWidth(buttonRect), 0, NSWidth(buttonRect), NSHeight(buttonRect));
                    offsetRight -= 1 * [self.buttons indexOfObject:button] + NSWidth(button.frame);
                    break;
                }
            }
            break;
        }

        case CNButtonBarAlignCentered: {
            break;
        }
    }
    [self addSubview:button];
}

更新2

問題は解決しました。いくつかのデバッグの後、私はそれがARCの自動保持/解放のものの問題であるに違いないことを発見しました。そして、私は正しいです。しかし、問題は私のNSViewControllerサブクラスでした。インスタンスをローカル変数(強力なポインターなし)として作成したため、リークが発生していました。Sean D.のおかげで、それは私に正しい道を示しました。(-;

4

1 に答える 1

2

2つのうちの1つが起こっているようです。最初の可能性は、ボタンがまだある間にCNButtonBarオブジェクトが解放されていることです。ボタンがまだそこにある場合は、CNButtonBarがあったメモリを占有するために、それらのセレクターを送信しようとします。どこにも自動リリースされていないこと、および誤っていないことを確認してください。ウィンドウコントローラの-awakeFromNibメソッドで自動リリースします。(あなたが私のような人なら、それが原因である可能性が最も高いです。)

2番目の可能性は、-addButtonWithTitle:image:target:action:alignment:メソッドがボタンのアクションを設定しているが、ターゲットは設定していないことです。-setTarget:そのメソッド呼び出しとボタンの実装を確認してください-setAction:

于 2012-07-29T03:42:01.610 に答える