【问题标题】:Objective-C Passing Method Reference As ParameterObjective-C 传递方法参考作为参数
【发布时间】:2023-03-13 01:44:01
【问题描述】:

我在这个主题附近看到了很多讨论,但没有一个真正适用于 Xcode 5.x,尤其是使用 ARC。我有一个简单的问题:

我需要将方法引用传递给 CreateButton 方法,以便在调用按钮时调用我的自定义函数,而不是一些通用函数。

我尝试过使用 (SEL) 类型,但这不适用于 ARC。我试过使用 &func 方法,但声称我还没有声明这个函数。

所以我的需要是:

Class A 调用 Class B 并发送信息以制作 UIButton。在该调用中,我想在参考中发送 action:method。我确信这是例行公事,但我似乎找不到 iOS 7 / Xcode 5.x 的方法。我还查看了 O'Reilly iOS 7 基础知识和食谱代码,但在任何地方都找不到讨论的内容。

感谢您的帮助。

【问题讨论】:

    标签: objective-c methods reference


    【解决方案1】:

    当我必须传递选择器时,我将它们转换为带有NSStringFromSelector() 的字符串,然后再转换回带有NSSelectorFromString() 的选择器。

    传递字符串要容易得多。您可以将它们存储在集合(数组、字典)中,对它们进行序列化和反序列化,它们将自然地与 ARC 一起使用。

    例子:

    在您收集信息以创建按钮的 A 类中:

    NSString *selectorString = NSStringFromSelector(@selector(yourActionMethodNameHere:));
    // Gather more information needed by Class B here, then package
    // it all up into a dictionary, for example
    NSDictionary *buttonInfo = @{@"selectorString": selectorString, /* more stuff here */};
    

    此时,您可以在 B 类中调用您的按钮构造方法,传递 buttonInfo,其中包含该辅助方法所需的所有信息,包括选择器。该方法可以将字符串转换回选择器并像这样使用它:

    SEL actionSelector = NSSelectorFromString(buttonInfo[@"selectorString"]);
    // configure your button to use actionSelector here
    

    【讨论】:

    • 如何调用 NSStringFromSelector()?我尝试了 NSStringFromSelector(func)、self.func、[self func]、(SEL)func。似乎没有任何效果。后半部分已完成并准备就绪!我不断收到一个错误,声称我的方法“func”没有在我的类中声明,但它对引用的方法是正确的。
    • 我加了一个小例子。显然我对你的用例了解不够,但你可以这样做。
    • TY。因此,由于某种原因,我在@selector 上不断收到此行的 ^ 错误,告诉我我的方法未声明。这与我班级的实例有关吗?该类只是引用自身。它是一个 UIViewController 试图处理它自己的按钮。因此,当您输入我的代码时,您的第一行因“未声明的选择器'test:'”而失败。 :(
    • 您的某个类是否实现了名为“test:”的方法?
    • 我终于让它工作了!非常感谢。我有一个错字,这让我很生气。 ARG。你是最棒的。
    【解决方案2】:

    你应该可以使用SEL参数吧?我知道我以前做过。 ARC 可能会抱怨并给你一个警告,但它不会编译失败。这只是一个警告,因为它无法完全弄清楚如何明智地做记忆。

    如果你真的不能让它工作,另一种选择是使用一个块,所以你可以调用你的方法

    [objectA performMethodWithParam:paramA paramb:paramB completion:^{ ... do somethhing ... }];
    

    然后在那个方法中你可以调用

    completion();
    

    而不是实际调用一个方法。

    另一种选择是使用委托模式。创建一个@protocol 定义一个方法,例如classADidFinish,然后让B 类实现该方法。然后将 classB 的实例设置为您的 classA 实例的委托,并让它在完成后调用该方法。

    这两种方法都会阻止 ARC 对你抱怨。

    但正如我所说,使用 SEL 参数应该可以正常工作。有一种方法甚至可以让编译器停止向您显示警告,但这有点难看。

    【讨论】:

    • 我研究过使用积木,但它太乱了。如果一个块不能简单地引用我的类中一个干净编写的方法,即 ^methodName,那么除非绝对必要,否则我不会看到自己使用它。
    猜你喜欢
    • 1970-01-01
    • 2014-07-14
    • 2011-09-13
    • 1970-01-01
    • 2010-12-12
    • 1970-01-01
    • 2018-09-09
    • 2019-12-28
    • 2014-03-05
    相关资源
    最近更新 更多