在没有子类化UIControl的情况下实现目标操作模式

时间:2013-04-12 13:04:56

标签: ios objective-c design-patterns

我正在为大学项目开发​​健身计时器应用程序。我的主计时器类是NSObject的子类。我希望其他对象能够注册定时器事件,例如定时器暂停,定时器完成等。我认为目标动作模式最适合这个,但我该如何实现呢?我需要能够为每个特定动作添加多个目标,就像UIButton一样。

感谢任何帮助。

3 个答案:

答案 0 :(得分:5)

这是添加多个目标的简单方法。显然,你想要构建一些错误检查并使其更灵活,但希望你能得到这个想法:

编写一种方法,允许其他对象将自己添加为目标:

- (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
     }
}

如果您不想使用UIControlEvents,则不必使用NSArrays来存储所有内容。这里重要的是你要挂在目标上,并将选择器存储为NSValue对象。

当发生某些事情时,请在对象上执行选择器:

- (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];
    }
}

请注意,如果选择器保留任何对象,您可能会遇到内存泄漏(Xcode会向您发出警告)。只要你的选择器没有返回他们创建/复制的对象,你应该没问题。有关performSelector潜在泄漏的更详尽的讨论,请参见:performSelector may cause a leak because its selector is unknown

答案 1 :(得分:1)

通知模式最适合您的应用。为此,您应该使用NSNotificationCenter

以下是一些教程
1
2

无法为行动添加多个目标(我认为)。

答案 2 :(得分:0)

您可以创建一个单例对象,并让对象从类对象请求该对象(就像Apple一样)。将相同的UIControl方法添加到您的类中,并在可变字典中注册对象和其他信息,通过使用** valueWithNonretainedObject:**方法将对象包装到NSValue对象中来保持对注册对象的弱引用。