ios UIControl类中的addTarget: action: forControlEvents: 方法认识

addTarget: action: forControlEvents:在我们开发中最为经常用的方法,尤其是UIButton。这个方法的最底层为UIControl类,在我们开发中用到它的,都是它子类。

UIControl类

UIControl是控件类的基类,它是一个抽象基类,我们不能直接使用UIControl类来实例化控件,它只是为控件子类定义一些通用的接口,并提供一些基础实现,以在事件发生时,预处理这些消息并将它们发送到指定目标对象上。

UIControl的是针对单点触摸,由于UIControl本身是视图,所以它实际上也继承了UIResponse。

为了判断当前对象是否正在追踪触摸操作,UIControl定义了一个tracking属性。该值如果为YES,则表明正在追踪。这对于我们是更加方便了,不需要自己再去额外定义一个变量来做处理。

UIControl的其它具体属性和特性可以观看这篇文章:http://www.cocoachina.com/ios/20160111/14932.html

这里主要说一下UIControl的Target-Action机制
Target-action是一种设计模式,直译过来就是目标-行为。当我们通过代码为一个按钮添加一个点击事件时,通常是如下处理:

[button addTarget:self action:@selector(tapButton:) forControlEvents:UIControlEventTouchUpInside];

也就是说,当按钮的点击事件发生时,会将消息发送到target(此处即为self对象),并由target对象的tapButton:方法来处理相应的事件。这里的target的对象是一个在内存中的,tapButton:的执行方法也是对象还存在。如果这两者不存在会出现崩溃现象。
例子:
我创建一个对象A是继承NSObject,在这个对象中写一个方法用来做执行的。这是我在UIControl分类B的一个方法中创建A,接着写Target-action,tapButton:的方法是A对象中方法。所有的都准备好了,执行的时候出现了崩溃。
代码:

- (void)clickOperation:(void (^) (void))perform style:(UIControlEvents)style {
    TYImplementCallback *back = [TYImplementCallback createImpLementCallback:perform];
    [self addTarget:back action:@selector(callback) forControlEvents:style];
}

为什么会出现这样的情况了。这是因为我对内存这个概论的认识不够深刻。继承NSObject的类创建的时候不用像其它可视化控件一样有一个add过程,这个add过程就是将对象的内存加入到堆中。而NSObject没有add所以它内存一直在栈中,只要一离开}这个对象的内存就没有了,而我们操作点击事件是在出了括号才执行的。所以会导致我们的程序就会崩溃。

解决这个方法还有就是

//这里的作用声明全局对象,它内存是放在这个大的对象堆中。是跟随大的对象内存消失而消失的。
@interface UIControl()

@end

中写一个全局声明的对象,然后在创建NSObject的类后,就这个对象赋值给我们刚才声明的全局对象。这样就能保证我们的NSObject对象不会出了括号就消失了。在分类当中没有set方法和get方法,也没有实例化属性发功能。我们可以通过runtime机制进行实现。
代码:

- (TYImplementCallback *)back{
    return objc_getAssociatedObject(self, &backKey);
}

- (void)setBack:(TYImplementCallback *)back {
    objc_setAssociatedObject(self, &backKey, back, OBJC_ASSOCIATION_RETAIN);
}

- (void)clickOperation:(void (^) (void))perform style:(UIControlEvents)style {
    self.back = [TYImplementCallback createImpLementCallback:perform];
    [self addTarget:self.back action:@selector(callback) forControlEvents:style];
}

在我们的开发现在虽然使用了ARC来进行内存管理,但是我们还是要对内存管理要有了解。什么样的情况是在堆中,什么样的情况是在栈中。我这两天的错误就是对内存的不太深入的了解。

你可能感兴趣的:(ios UIControl类中的addTarget: action: forControlEvents: 方法认识)