在Objective-C块中,能否使外部方法返回?红宝石工艺?
在Ruby中,在块或嵌套块内调用在Objective-C块中,能否使外部方法返回?红宝石工艺?,objective-c,ruby,closures,Objective C,Ruby,Closures,在Ruby中,在块或嵌套块内调用return,将从最内层的包装方法(我说的是proc)转移控制和返回。在Ruby中,lambdareturn从块本身返回,调用方法继续,Objective-C块也是这样工作的 有没有办法让Ruby的proc语义w.r.t在Objective-C中返回?我希望在块内返回,以返回外部方法。简短的回答是否,块内的return语句将仅从块返回。如下图所示,您当然可以结合使用异常、@try语句和宏来构建一些不雅观的东西,但最终我认为这比其他任何东西都更令人困惑 @inter
return
,将从最内层的包装方法(我说的是proc)转移控制和返回。在Ruby中,lambdareturn
从块本身返回,调用方法继续,Objective-C块也是这样工作的
有没有办法让Ruby的proc语义w.r.t在Objective-C中返回?我希望在块内返回,以返回外部方法。简短的回答是否,块内的return语句将仅从块返回。如下图所示,您当然可以结合使用异常、
@try
语句和宏来构建一些不雅观的东西,但最终我认为这比其他任何东西都更令人困惑
@interface MPReturnFromNestedBlockException : NSException
+ (void) returnExceptionWithResult:(id)result;
@end;
@implementation MPReturnFromNestedBlockException
+ (void) returnExceptionWithResult:(id)result
{
MPReturnFromNestedBlockException *exception = (id)
[self exceptionWithName:@"MPReturnFromMethodException"
reason:nil
userInfo:@{@"result":result}];
[exception raise];
}
@end
#define abruptReturn(value)\
({ [MPReturnFromNestedBlockException returnExceptionWithResult:value]; })
#define blockMayReturnAbruptly(block)\
({\
id result = nil;\
@try { block(); }\
@catch(MPReturnFromNestedBlockException *exception) {\
result = exception.userInfo[@"result"];\
}\
result;\
})
int main (int argc, const char * argv[])
{
@autoreleasepool {
NSArray *numbers = @[@1, @2, @3];
id value = blockMayReturnAbruptly(^{
[numbers enumerateObjectsUsingBlock:^(id numA, NSUInteger index, BOOL *stop) {
double a = [numA doubleValue];
[numbers enumerateObjectsUsingBlock:^(id numB, NSUInteger index, BOOL *stop) {
double b = [numB doubleValue];
NSLog(@"%f x %f = %f", a, b, a*b);
if (a * b > 3)
abruptReturn(@(a*b));
}];
}];
});
NSLog(@"Result = %@", value);
}
return 0;
}
输出如下:
1.000000 x 1.000000 = 1.000000
1.000000 x 2.000000 = 2.000000
1.000000 x 3.000000 = 3.000000
2.000000 x 1.000000 = 2.000000
2.000000 x 2.000000 = 4.000000
Result = 4
我不熟悉Ruby,但是ObjC块控制其封闭方法的唯一方法是该方法测试其返回值 这可以简单到:
- (id)bloviate:(id (^)(void))bombast
{
// The method returns the results of the Block call;
// thus, strictly speaking, the method returns when
// the Block does.
return bombast();
}
或者,您可以检查返回值并有条件地从方法返回:
- (id)elucidate:(BOOL (^)(id))explanation
{
id obj = /* Get some object */;
if( explanation(obj) ) {
return obj;
}
// Else continue
}
这是一个很好的想法,但异常并不打算用于ObjC中的控制流。您还可以补充说,它可能无法很好地处理经常使用块的多线程代码。我已经检查过了,当从另一个线程使用返回宏时,它肯定不起作用。这很有意义,因为异常跟踪机制尚未安装在正在运行的线程的调用堆栈上。如果块在其定义的方法的范围之外运行,那么返回将执行什么操作?@newacct:return从其运行的范围返回,如Ruby。。。最坏情况
main