2012-10-20 57 views
0

我是新来的ios,来自C#中沉重的用户界面工作。 我有一个应用程序,我想控制哪些按钮启用禁用基于我的代码中的某些逻辑。 做到这一点,我创建了一个小方法来处理按钮的状态,就像这样:ios,用户界面行为,按钮

-(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) 我究竟做错了什么?

回答

1

编辑:我的,我的。我刚刚意识到我有多糟糕。

错误:首先,你不应该使用BOOL *,如果你做过使用BOOL *你将其引用为&activate,不*activate。 C/Objective-C中的*表示该变量是一个指针;它包含一个内存块的地址。 &解除引用指向访问另一端的值。

正确:一个*表示该参数是一个指针,也用于指针的指针。变量前面的&表示您要使用内存中变量的地址。我混淆了他们。这意味着您的原始代码是正确的;问题是,你可能把它用[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]; 

如果你真的意味着一个指针传递给一个BOOL作为参数使用你原来写,但你需要调用它像这样:

[self activateUI: &someBOOL]; 

如果您声明方法采用指向BOOLBOOL *)的方法,并在方法主体(*someBOOL)内对其进行取消引用,则需要将地址传递给BOOL&someBOOL),而不是BOOL本身。如果您声明方法采用BOOL本身(仅为BOOL),并直接在方法体(someBOOL)中使用它,则需要通过BOOL本身(someBOOL)。

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)