How to create custom exception in objective c?

前端 未结 2 1687
有刺的猬
有刺的猬 2021-01-05 18:23

I am trying to achieve something like this in objective c.

@try{
//some code that will raise exception
}
@catch(CustomException e){//How to create this
//cat         


        
相关标签:
2条回答
  • 2021-01-05 18:34

    In the simplest case, I can declare a class using...

    @interface CustomException : NSException
    @end
    @implementation CustomException
    @end
    

    ...and the code is very much like what you posted:

       @try{
            @throw [[CustomException alloc] initWithName:@"Custom" reason:@"Testing" userInfo:nil];
        }
        @catch(CustomException *ce){
            NSLog(@"Caught custom exception");
        }
        @catch(NSException *e){
            NSLog(@"Caught generic exception");
        }
    
    0 讨论(0)
  • 2021-01-05 18:42

    Exceptions are very rarely used for control flow like this in Objective-C. I'm guessing you have a Java (or similar) background.

    I'm not saying that you can't write code like this but it will feel very strange for other people looking at your code and could also possibly work badly if used by other peoples code if you don't completely isolate the exceptions so that it never reaches their code.

    How it is commonly done in Objective-C

    Exceptions are used for critical errors. If the error is expected (like it seems to be since you want to @try it) you should instead try and return an NSError. This is a design pattern that is used all over the Foundation and Cocoa frameworks and also third party frameworks. Look for example at networking, file reading/writing or JSON code (JSONObjectWithData:options:error:)

    What you would do

    What you do is add a error parameter (double pointer) at the end of your method that could fail, like this:

    - (MyResultObject *)myMethodThatCouldFailWith:(MyObject *)myObject
                                            error:(NSError **)error;
    

    When someone (you or someone else) uses this method they can if they want to pass a NSError pointer that will get set if an error occurred, like this:

    NSError *error = nil; // Assume no error
    MyResultObject *result = [self myMethodThatCouldFailWith:myObject
                                                       error:&error];
    if (!result) {
        // An error occurred, you can check the error object for more information.
    }
    

    Note the ampersand (&) before the error parameter. This means that you are sending your error points as the argument so that inside the risky method that pointer can be changed to points to a new NSError object which can be read after the method returns.

    Now, inside your method that could fail, you would set the error to a new NSError object if something went wrong (instead of raising an exception). It is also very common to return nil when an error occurs since that probably means that the calculation won't be able to complete or that the data is unreliable or irrelevant.

    - (MyResultObject *)myMethodThatCouldFailWith:(MyObject *)myObject
                                            error:(NSError **)error {
        // Do something "risky" ...
        MyResultObject *result = [MyResultObject somethingRiskyWith:myObject];
        
        // Determine if things went wrong
        if (!result) {
            // Set error if a pointer for the error was given 
            if (error != NULL) {
                *error = [NSError errorWithDomain:yourErrorDomain
                                             code:yourErrorCode
                                         userInfo:optionalDictionaryOfExtraInfo];
            }
            return nil;
        }
        
        // Everything went fine.
        return result;
    }
    

    Now if the error returns you can identify what kind of error it was from the error code that you specified and you can read more detailed information in the user info dictionary (where you can add lots of information).

    0 讨论(0)
提交回复
热议问题