0

我是 ios 新手,来自 C# 中繁重的 UI 工作。我有一个应用程序,我想根据我的代码中的一些逻辑来控制哪些按钮被禁用。为此,我创建了一个小方法来处理按钮的状态,如下所示:

-(void)activateUI:(BOOL *)activate {

    [ validateDataBtn setEnabled: *activate ] ;
    [ modifyCompDataBtn setEnabled: *activate ] ;
    [ saveCompDataBtn setEnabled: *activate ] ;
}

所有这些 IBOutlets 都绑定到 UI 按钮,如下所示:

__weak IBOutlet UIButton *saveCompDataBtn;
__weak IBOutlet UIButton *modifyCompDataBtn;
__weak IBOutlet UIButton *validateDataBtn;

当我运行应用程序时,我的方法的第一行出现异常:

[ validateDataBtn setEnabled: *activate ] ;

错误是 EXC_BAD_ACCESS(代码 = 2,地址 = 0X0)我做错了什么?

4

2 回答 2

1

为什么不

- (void)activateUI:(BOOL)activate {
    [validateDataButton setEnabled:activate];
    // etc...
}

我不确定为什么需要使用指向BOOL激活的指针...

编辑:

作为标量与指针访问的说明:

#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>

@interface Foo:NSObject
@property (nonatomic, retain) NSTextField *field;
- (void)activateUI:(BOOL *)activate;
- (void)activateUIScalar:(BOOL)activate;
@end

@implementation Foo
@synthesize field;

- (void)activateUI:(BOOL *)activate {
    NSLog(@"%s - setting to: %d",__FUNCTION__,*activate);
    [[self field] setEnabled:*activate];
}

- (void)activateUIScalar:(BOOL)activate {
    NSLog(@"%s - setting to %d (scalar)",__FUNCTION__, activate);
    [[self field] setEnabled:activate];
}

@end

int main(int argc, char *argv[]) {
    NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];

    BOOL flag = NO;
    Foo *myFoo = [Foo new];
    [myFoo activateUI:&flag];

    flag = YES;
    [myFoo activateUI:&flag];

    //  now using scalar (99.999% of the time the right way)
    [myFoo activateUIScalar:YES];
    [myFoo activateUIScalar:NO];

    [myFoo release];
    [p release];
}

将以下内容打印到控制台:

2012-10-20 14:49:14.228 Untitled 4[27444:707] -[Foo activateUI:] - setting to: 0
2012-10-20 14:49:14.230 Untitled 4[27444:707] -[Foo activateUI:] - setting to: 1
2012-10-20 14:49:14.230 Untitled 4[27444:707] -[Foo activateUIScalar:] - setting to 1 (scalar)
2012-10-20 14:49:14.231 Untitled 4[27444:707] -[Foo activateUIScalar:] - setting to 0 (scalar)
于 2012-10-20T19:32:20.550 回答
1

编辑:我的,我的。我才意识到我把这个搞砸了。

不正确:首先,您不应该使用BOOL *,如果您曾经使用过,BOOL *您会将其引用为&activate,而不是*activate。C/Objective-C 中的*表示变量是指针;它包含一个内存块的地址。&取消引用指针以访问另一侧的值。

正确: An*表示参数是一个指针,也用于引用一个指针。变量前面的an&表示要使用该变量在内存中的地址。我把它们混在一起了。这意味着您的原始代码是正确的;问题是您可能使用 调用它[self activateUI:someBOOL],它传递一个 BOOL,然后由于*.

您可能会感到困惑,因为传递对象是<object type> *因为用于处理对象实例的所有变量都是指针。然而,BOOL 被typedef编辑为int,这是原始的,因此*不需要 。你的方法应该是:

- (void) activateUI:(BOOL)activate {
    [validateDataBtn setEnabled: activate];
    [modifyCompDataBtn setEnabled: activate];
    [saveCompDataBtn setEnabled: activate];
}

//called like this: [self activateUI: someBOOL];

如果您真的打算将指向 a 的指针BOOL作为参数传递,请使用您最初编写的内容,但您需要像这样调用它:

[self activateUI: &someBOOL];

如果您声明该方法获取指向BOOL( BOOL *) 的指针,并在方法主体 ( *someBOOL) 内取消引用它,则需要将地址传递给BOOL( &someBOOL),而不是BOOL本身。如果将方法声明为取BOOL自身(just BOOL),并直接在方法体(someBOOL)中使用,则需要传递BOOL自身(someBOOL)。

于 2012-10-20T19:34:45.380 回答