以编程方式向按钮添加操作
Posted
技术标签:
【中文标题】以编程方式向按钮添加操作【英文标题】:Add action to button programmatically 【发布时间】:2014-02-16 13:37:05 【问题描述】:我正在尝试从自定义类中。但是,我在执行操作时不断收到错误消息。我已经阅读了很多有关如何执行此操作的信息,但显然在某处犯了错误,无法弄清楚在哪里。
首先通过将按钮拖到情节提要上来创建按钮。然后我控制拖动到 ViewControler.h 文件来得到这个:
@property (strong, nonatomic) IBOutlet UIButton *testButtonForClass;
在 ViewControler.m 中,我这样做:
- (void)viewDidLoad
[super viewDidLoad];
testClass *myClass = [[testClass alloc]init];
myClass.myButton = self.testButtonForClass;
[myClass assignActionTargets];
下面是自定义类的Header和Implementation文件。
头文件
#import <Foundation/Foundation.h>
@interface testClass : NSObject
@property (nonatomic, strong) UIButton *myButton;
-(void)assignActionTargets;
@end
实施文件
#import "testClass.h"
@implementation testClass
-(void)assignActionTargets
[self.myButton addTarget:
self action:@selector(myButtonInnerTap)
forControlEvents:(UIControlEventTouchUpInside)];
-(void)myButtonInnerTap
UIAlertView *a = [[UIAlertView alloc]initWithTitle:nil
message:@"testClass says hello"
delegate:nil
cancelButtonTitle:@"Dismiss"
otherButtonTitles:nil, nil];
[a show];
@end
【问题讨论】:
你遇到了什么错误? 我是 Objective-C 的新手,不擅长使用调试器。程序可以编译,但是当我单击已分配类按钮的按钮时,我得到了这个:EXC_BAD_ACCESS(code=2, address=0x8), in Main.m 添加异常断点,看看能不能得到更好的信息。请参阅此问题以了解如何设置***.com/questions/17802662/…otherButtonTitles:nil, nil];
也尝试删除多余的 nil
你能粘贴控制器的代码吗?你是如何在点击按钮时调用函数的。
【参考方案1】:
您创建了一个testClass
实例,但没有保留对它的引用,因此它在viewDidLoad
结束时被释放。
- (void)viewDidLoad
[super viewDidLoad];
TestClass *myClass = [[TestClass alloc] init];
myClass.myButton = self.testButtonForClass;
[myClass assignActionTargets];
// myClass gets deallocated here!
单击按钮时,它会尝试访问您指定的目标,但现在这是指向无效内存段的悬空指针,因此会导致崩溃。
您必须保持对myClass
的强引用,以便在单击按钮时使其保持活动状态。声明一个强大的属性是实现这一目标的好方法。
@property (nonatomic, strong) TestClass *myThingy;
- (void)viewDidLoad
[super viewDidLoad];
self.myThingy = [[testClass alloc] init];
self.myThingy.myButton = self.testButtonForClass;
[self.myThingy assignActionTargets];
代码风格说明:请使用一些命名约定。类名应该大写(我已经在上面的 sn-ps 中更改了它,因为它杀死了我......)并且使用 myClass
指向类的 instance 的指针是完全迷失方向的。
【讨论】:
这行得通。谢谢你,@Gabriele。正如您所指出的,我没有正确使用对象范围。我还有一个问题:在这种情况下,将“非原子”更改为“原子”有什么区别? 没有显着差异。atomic
将生成使用内部锁的访问器方法,从而导致实现速度变慢。 atomic
本身并不能保证线程安全,所以在 99% 的情况下,nonatomic
更明智。【参考方案2】:
首先,参数otherButtonTitles
的双重nil
是“有问题的”。减少到一个。
其次,确保调用类正确保留按钮和对象。
最后,通过NSLog
或断点确保有问题的对象(自定义对象、按钮)不为零。
【讨论】:
出于兴趣,为什么双重nil
有问题?
我认为应该有一个以 nil 结尾的列表。两个nil
s 的行为是未定义的。有问题的、丑陋的、不必要的、分散注意力的 - 删除。
是的,我将采用 undefined behaviour
参数。
nil
终止列表在遇到第一个 nil
时立即终止,忽略其余的。我同意这是丑陋的,不必要的和分散注意力的,但它没有问题。
@GabrielePetronella 这就是为什么我最初质疑该评论的原因,但我认为 Mundi 击中了头部它未定义,因此它不安全。如果现在有效,将来可能不会以上是关于以编程方式向按钮添加操作的主要内容,如果未能解决你的问题,请参考以下文章