I believe those of you who have done iOS development are familiar with UIButton, as long as you have used UIButton, – (void)addTarget (Nullable ID) Target Action (SEL) Action forControlEvents (UIControlEvents)controlEvents; But what does this approach actually do?

Before starting this article, a few questions?

  1. What happens when we click the button to the response event?
  2. Does UIButton hold target?
  3. Can target be nil, and if it can be nil, what does the system do?
  4. Can actions be nil?

What happens when we click the button to the response event?

Since it can call our methods when we click, I guess it should store things like target, action, and event so we can call them when we click. So I’m going through the instance variables and properties of UIButton and its parent class, UIControl. Found this instance variables in the UIControl targetActions he is of type NSMutableArray, targetActions UIControlTargetAction put inside. This class is a Model class with four simple attributes: _target type ID, _action type SEL, _eventMask type unsigned long long, and _Cancelled type bool. _target,_action,_eventMask, target, Action,controlEventt.

So we should be able to guess. – (void)addTarget (Nullable ID) Target Action (SEL) Action forControlEvents (UIControlEvents)controlEvents; UIButton generates a UIControlTargetAction object based on the information we passed and puts it in an array. When we touch the button, we iterate through the array based on the event. If the event is the same as the eventMask of model in the array, The [UIControlTargetAction target performSelector: UIControlTargetAction action withObject: self], of course, there was a series of judgment.

Does UIButton hold target?

According to the documentation, Button does not hold target, and the documentation does not deceive us, but I tested it anyway, and the test code is as follows

[btn addTarget:person action:@selector(btnAction) forControlEvents:UIControlEventTouchUpInside]; #import "person. h" @implementation Person - (void)btnAction{NSLog(@"btnAction"); } - (void)dealloc{ NSLog(@"%@----dealloc",[self class]); } @end output: Person----deallocCopy the code

If the BTN holds the Target person, it will not use the Person dealloc method

What happens if the same event is added multiple times

[btn addTarget:self action:@selector(firstAction) forControlEvents:UIControlEventTouchUpInside];
[btn addTarget:self action:@selector(secondAction) forControlEvents:UIControlEventTouchUpInside];
Copy the code

I added two separate actions for BTN’s TouchUpInside event, which it calls in the order it added them. In the code above, when I click BTN, it calls firstAction and secondAction. If you change the _eventMask value of the UIControlTargetAction object in the firstAction method, the secondAction will not be called.

Whether target can be nil

And the answer is yes, it can be nil if target is nil and instead of sending a message to nil, it’s looking up the responder chain, and if it finds it, it calls it, otherwise it doesn’t do anything.

[btn addTarget:nil action:@selector(btnAction) forControlEvents:UIControlEventTouchUpInside];
Copy the code

In other words, the code above checks to see if the BTN class implements the btnAction method, and if it does, it calls it, otherwise it looks for btn.nextresponder, checks again, all the way to the AppDelegate, and does nothing if it hasn’t implemented it yet.

Whether action can be NULL

The documentation states that the action cannot be NULL, but my tests found that when the action is NULL, the program will run without error. I do not know whether Apple added judgment without updating the document or there is something wrong with my test method. The test code is as follows

SEL btnAction = NULL;
[btn addTarget:self action:btnAction forControlEvents:UIControlEventTouchUpInside];
Copy the code

Nothing happens when I click on BTN. I don’t know why the description on the document is inconsistent.