【问题标题】:Error propagatin inside try/catch in cocoa可可中 try/catch 中的错误传播
【发布时间】:2012-08-04 12:33:13
【问题描述】:

我想在一个方法的 catch 块内引发一个异常,并在另一个方法的 catch 中处理它,从该方法调用了之前的方法。 我试过这个逻辑-

method B()
{
    @try{
        .......
        // calling method where is probable chance of exception


    method A();
    }
    catch(NSException e)
    {
        //catching the exception thrown in the method B()
        NSString* theError=[e reason];
        NSLog(@"the error is == %@",theError);
    }
}

method A()
{
    @try{
        .............
        //throw an exception incase of some condition
        throw e;
    }
    catch(NSException e)
    {
        //rethrowing the exception, want to catch in the method from where this method is called.  
        throw e;
    }
}

但是方法 B() 的 catch 块永远无法访问。 控件永远不会返回到方法 B() 的 catch 块。 请提出建议。

谢谢, 苏丹苏


这里有一些代码。我正在从 MyController 调用 TableController 的方法(populateData)。 应该在 TableController(initializeTest) 的另一种方法中发生的异常,我正在抛出它 在 FinderCompleted 方法的 try 块内。在同一方法的 catch 块中,重新抛出异常,如 我不想在这里处理它。 该控件仅限于方法的最里面的 catch 块 - (void)FinderCompleted:(id)args NSLog 像这样打印- 我在这里 1 内部错误 你的桶里什么都没有:D 第一次抛出异常 Gotcha--第一次异常,第二次抛出 错误是==发生了意外的事情--EXCEPTION

在那之后,我不知道控件的去向。我希望控件去捕获调用 FinderCompleted 方法的外部方法的块, 并打印其他日志,例如- Gotcha--第二次异常,第三次抛出 Gotcha--第三次异常 第四次抛出异常 Gotcha--第四次异常 错误是发生了意外的事情--EXCEPTION


in MyController.m

- (IBAction)fetchResults:(id)sender
{
    NSArray *tableColumnArray = ...............;//some values initialized
    NSArray *identifierArray = ................;//some values initialized
    NSArray *bindVariableArray = ................;//some values initialized
    TableController *pTC = [[TableController alloc] init];
    @try
    {
        [pTC populateData :tableColumnArray :identifierArray :bindVariableArray];// calling populate DataForMD method defined in  TableController class
        [pTC release];
    }
    @catch (NSException * e)
    {
        NSLog(@"Gotcha--4th time exception");
        //want to handle the exception here 
        NSString* theError=[e reason];
        NSLog(@"the error is %@",theError);
    }
}

在 TableController.m 中

-(void)populateData:(NSArray *)tableColumnArray:(NSArray *)identifierArray:(NSArray *)bindVariableArray
{
    [self setTableColumnArray:tableColumnArray];
    [self setColumnIdentifierArray:identifierArray];
    [self setBindVarArray:bindVariableArray];
    @try
    {
        NSLog(@"m here 1");
        [self initializeTest];// calling initializeTest method 
    }
    @catch (NSException * e)
    {
        //Do not want to handle it here 
        NSLog(@"Gotcha--3rd time exception");
        NSLog(@"Throwing exception for the 4th time");
        @throw e;
    }
}

-(void)initializeTest
{
    @try
    {
        ISTQuery* theQuery = (ISTQuery*)[ISTQueryGenerator getQueryByName:[self queryClassName]];
        ..........
        ...........//some loc here
        [theQuery run];
        .................//some loc here
        if(theQuery)
        {
            //Calling FinderCompleted method 
            //supposed to get error here
            [[self modelFinder] startWithRecipient:self andNotificationSelector:@selector(FinderCompleted:)];
        }
    }
    @catch(NSException *e) 
    {
        NSLog(@"Gotcha--2st time exception, throwing it 3rd time");
        //Do not want to handle it here 
        @throw e; // rethrows e implicitly
    }
}

- (void)FinderCompleted:(id)args
{
    @try
    {   //getting some error while back-end transaction 
        NSString* theError = [ISTModelFinder errorMessageFromFinderArgs:args];
        if (theError)
        {
            NSLog(@"Inside the error");
            NSLog(@"You got nothing in ur bucket :D");
            NSException *e = [NSException
                              exceptionWithName:@"InternalErrorException"
                              reason:@"Something unexpected happened --EXCEPTION"
                              userInfo:nil];
            NSLog(@"Throwing exception for the 1st time");
            @throw e;
        }       
        else
        {
            //do sth else
        }
    }   
    @catch(NSException *e) 
    {
        NSLog(@"Gotcha--1st time exception , throwing it 2nd time");
        NSString* theError=[e reason];
        //Do not want to handle it here 
        NSLog(@"the error is == %@",theError);
        @throw e; // rethrows e implicitly
    }
}   

【问题讨论】:

  • 请努力正确缩进您的代码,使其更具可读性。我已经为你做了一次:-)

标签: objective-c cocoa exception exception-handling try-catch


【解决方案1】:

在 Cocoa 或 iOS 编程中,您不能使用异常进行流控制。异常纯粹是为了识别不可恢复的错误,通常情况下,程序会在此后不久故意崩溃。 (此规则有少数例外情况,其中大多数都有针对他们的错误,以弃用和消除相关 API。)

使用NSError 模式来管理用户可恢复的错误。

尚不清楚您的代码为何不起作用。但这看起来不像真正的代码。你试过什么?


我已经添加了代码 sn-p,请建议如何实现 功能。

你要做的第一件事是不要使用异常

使用 NSError 模式。您需要重构代码才能做到这一点。这是值得的。

请参阅error handling in cocoa 上的文档。

【讨论】:

  • 如果NSExceptions 后面没有星号,它还能编译吗?
  • 也许你没有正确理解 bbum。在 Cocoa / Cocoa Touch 中,您不会抛出异常来处理意外错误。相反,您使用 NSError。错误可以使用间接指针“抛出”。更多信息在这里:developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/…
  • 我已经添加了代码 sn-p,请建议如何实现该功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-31
  • 2017-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多