Implement target-action pattern without subclassing UIControl
design-patterns, ios, objective-c
Solution
Here's a simple way to add multiple targets. Obviously, you'd want to build in some error checking and make it a little more flexible, but hopefully you get the idea:
Write a method that allows other objects to add themselves as a target:
- (void) addTarget:(NSObject *)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents {
if (controlEvents == UIControlEventValueChanged) {
NSArray *targetAndAction = @[target, [NSValue valueWithPointer:action]];
[valueChangedArray addObject:targetAndAction]; // valueChangedArray is a NSMutableArray, already initialized
}
}
You don't have to use UIControlEvents if you don't want to, and you don't have to use NSArrays to store all the stuff. The important thing here is that you're hanging on to the target, and storing the selector as an NSValue object.
When something happens, perform the selector on the object:
- (void) somethingHappened {
// something happened, inform the objects who registered
for (NSArray *targetAndAction in valueChangedArray) {
NSObject *target = targetAndAction[0];
NSValue *actionValue = targetAndAction[1];
SEL action = [actionValue pointerValue];
[target performSelector:action];
}
}
Note that you may get a memory leak if the selector retains any objects (Xcode will warn you about this). As long as your selectors aren't returning objects they created / copied, you should be OK. More thorough discussion on the performSelector potential leak is available here: performSelector may cause a leak because its selector is unknown.
Problem
I'm developing an gym timer application for a college project. My main timer class is a subclass of NSObject. I want other objects to be able to register for timer events such as timer paused, timer finished, etc. I think the target-action pattern would be most suitable for this but how would I implement this? I need to be able to add multiple targets for each specific action, the same way UIButton does this. Any help is appreciated.