以编程方式向按钮添加操作

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 结尾的列表。两个nils 的行为是未定义的。有问题的、丑陋的、不必要的、分散注意力的 - 删除。 是的,我将采用 undefined behaviour 参数。 nil 终止列表在遇到第一个 nil 时立即终止,忽略其余的。我同意这是丑陋的,不必要的和分散注意力的,但它没有问题。 @GabrielePetronella 这就是为什么我最初质疑该评论的原因,但我认为 Mundi 击中了头部它未定义,因此它不安全。如果现在有效,将来可能不会

以上是关于以编程方式向按钮添加操作的主要内容,如果未能解决你的问题,请参考以下文章

Android:以编程方式向通知添加按钮

以编程方式向表格视图单元格添加按钮[关闭]

以编程方式向 Swift 中的视图添加约束时出错

UITableView以编程方式调用滑动操作

以编程方式将按钮添加到集合视图单元格

以编程方式向 UIView 添加约束