Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Objective-C块中,能否使外部方法返回?红宝石工艺?_Objective C_Ruby_Closures - Fatal编程技术网

在Objective-C块中,能否使外部方法返回?红宝石工艺?

在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

在Ruby中,在块或嵌套块内调用
return
,将从最内层的包装方法(我说的是proc)转移控制和返回。在Ruby中,lambda
return
从块本身返回,调用方法继续,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