【问题标题】:Implement target-action pattern without subclassing UIControl在不继承 UIControl 的情况下实现目标动作模式
【发布时间】:2013-04-12 13:04:56
【问题描述】:

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

感谢任何帮助。

【问题讨论】:

    标签: ios objective-c design-patterns


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

      这里有一些教程
      1
      2

      为一个动作添加多个目标是不可能的(我认为)。

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-05-09
          • 2018-12-06
          • 2017-05-13
          相关资源
          最近更新 更多