ios,UI行为,按钮

时间:2012-10-20 19:00:13

标签: objective-c ios

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

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

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

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

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

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

[ validateDataBtn setEnabled: *activate ] ;

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

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

编辑:我的,我的。我刚刚意识到我搞砸了这个问题。

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

正确:*表示参数是指针,也用于表示指针。变量前面的&表示您要在内存中使用变量的地址。我把它们搞混了。这意味着您的原始代码是正确的;问题是你可能使用[self activateUI:someBOOL]来调用它,它传递一个BOOL,然后尝试将它作为指针推导出来,因为*

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

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

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

如果你真的DID意味着将指针传递给BOOL作为参数使用你最初编写的内容,但是你需要像这样调用它:

[self activateUI: &someBOOL];

如果声明方法采用指向BOOLBOOL *)的指针,并在方法体(*someBOOL)内取消引用它,则需要将地址传递给BOOL&someBOOL),而非BOOL本身。如果您声明方法采用BOOL本身(仅BOOL),并直接在方法体(someBOOL)中使用它,则需要传递BOOL本身(someBOOL)。