我是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) 我做错了什么?
答案 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 typedef
为int
,这是原始的,因此不需要*
。你的方法应该是:
- (void) activateUI:(BOOL)activate {
[validateDataBtn setEnabled: activate];
[modifyCompDataBtn setEnabled: activate];
[saveCompDataBtn setEnabled: activate];
}
//called like this: [self activateUI: someBOOL];
如果你真的DID意味着将指针传递给BOOL
作为参数使用你最初编写的内容,但是你需要像这样调用它:
[self activateUI: &someBOOL];
如果声明方法采用指向BOOL
(BOOL *
)的指针,并在方法体(*someBOOL
)内取消引用它,则需要将地址传递给BOOL
(&someBOOL
),而非BOOL
本身。如果您声明方法采用BOOL
本身(仅BOOL
),并直接在方法体(someBOOL
)中使用它,则需要传递BOOL
本身(someBOOL
)。