存储对数组中对象方法的引用(Objective-C)

时间:2016-05-04 03:52:14

标签: ios objective-c nsarray

我正在学习Objective-C,我正在尝试将方法引用存储在一个数组中,我可以遍历数组并调用方法。我来自一个解释性语言背景,并且使用像Ruby这样的语言,你可以做类似下面的事情

method_arr = [objectOne.method(:methodOne), objectTwo.method(:methodOne)]

method_arr.each do |m|
    m.call
end

我发现最接近的是使用NSInvocation来实现以下

NSMethodSignature *signature = [objectOne methodSignatureForSelector:@selector(methodOne)];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setSelector:@selector(methodOne)];
[invocation setTarget:objectOne];


NSArray *methodArr = @[invocation];

for (int i = 0; i < [methodArr count]; i++) {
    [methodArr[i] invoke];
}

我发现的另一种方法是使用不引用方法但实现类似结果的块

NSArray *methodArr = @[^{ 
    [objectOne methodOne]
}];

NSInvocation对我来说似乎有点乏味,并且想知道是否有更好的方法来做到这一点。

2 个答案:

答案 0 :(得分:0)

我会选择积木。创建数组时,将每个方法调用包装在一个块中并添加该块。

NSArray *calls = @[
                   ^{ [classInstance methodOne; },
                   ^{ [classInstance methodTwo; },
                   ^{ [classInstance methodThree; },
                   ^{ [classInstance methodFour; },
                 ];

注意这种方法的内存问题;具体参考周期。您可能希望classInstance成为弱引用。

您可以通过转换为dispatch_block_t并调用来调用块。

((dispatch_block_t)calls[0])();

您可以通过键入数组来使其更清洁。

NSArray<dispatch_block_t> *calls = @[

现在调用只是

calls[0]();

答案 1 :(得分:0)

我会使用数组中的字符串。只需将方法名称存储在数组中,循环数组,将方法名称字符串转换为选择器NSSelectorFromString(),然后在对象上调用performSelector:。但是,这可能会导致不必要的警告

  

performSelector可能导致泄漏,因为它的选择器未知

可以通过将performSelector:代码包含在这些pragma

中来删除
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    [object performSelector: someSelector withObject: anotherObject];
#pragma clang diagnostic pop

here

中解释 祝你好运,希望这很有帮助!