【发布时间】:2017-06-21 19:20:49
【问题描述】:
我创建了一个 Objective-c 方法,它将通过 NSInvocation 调用一个方法:
typedef void (^ScriptingEmptyBlock)();
typedef void (^ScriptingErrorBlock)(NSError *error);
- (void)scripting_execute:(NSString *)operation withParams:(nullable NSArray *)args {
SEL selector = [self scripting_selectorForOperation:operation];
Class class = [self class];
NSMethodSignature *signature = [class instanceMethodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setSelector:selector];
[invocation setTarget:self];
for (int idx = 0; idx < args.count; idx ++) {
id arg = args[idx];
[invocation setArgument:&arg atIndex:idx + 2];
}
ScriptingEmptyBlock success = args[1];
// Breakpoint added on next line to test for nil
success(); // this is nil and would crash!
// (lldb) po args.count
// 3
// (lldb) po success
// Printing description of success:
// (ScriptingEmptyBlock) success = 0x0000000000000000
// (lldb) po args[1]
// (Function)
//[invocation getArgument:&success atIndex:2]; // also tried this and got nil as well
[invocation invoke];
}
该方法采用“操作”,通过覆盖子类中的scripting_selectorForOperation: 将其转换为选择器,然后执行调用。
所有这些都有效,除了当调用的方法具有块参数时它们为 nil,我添加了我用 cmets 描述的 nil 测试,当尝试从数组中读取闭包时,它将为 nil。
调用如下:
let successClosure: ScriptingEmptyBlock = {
print("Renamed product")
}
let errorClosure: ScriptingErrorBlock = { error in
print("Failed to rename product: \(error)")
}
let params:[Any] = [ "testName", successClosure, errorClosure]
object.scripting_execute (ScriptOperation.updateProductName.rawValue, withParams: params)
为什么闭包变为零了?
【问题讨论】:
标签: ios objective-c memory-management swift3 objective-c-blocks