2011年7月19日 星期二

Object-C 進階學習[ 異常情況(Exceptions) ]

  • 異常處理只有 Mac OS X 10.3 UP 才支援。
  • CupWarningException.h
    #import <Foundation/NSException.h>
    
    @interface CupWarningException: NSException
    @end
  • CupWarningException.m
    #import "CupWarningException.h"
    
    @implementation CupWarningException
    @end
  • CupOverflowException.h
    #import <Foundation/NSException.h>
    
    @interface CupOverflowException: NSException
    @end
  • CupOverflowException.m
    #import "CupOverflowException.h"
    
    @implementation CupOverflowException
    @end
  • Cup.h
    #import <Foundation/NSObject.h>
    
    @interface Cup: NSObject {
        int level;
    }
    
    -(int) level;
    -(void) setLevel: (int) l;
    -(void) fill;
    -(void) empty;
    -(void) print;
    @end
  • Cup.m
    #import "Cup.h"
    #import "CupOverflowException.h"
    #import "CupWarningException.h"
    #import <Foundation/NSException.h>
    #import <Foundation/NSString.h>
    
    @implementation Cup
    -(id) init {
        self = [super init];
    
        if ( self ) {
            [self setLevel: 0];
        }
    
        return self;
    }
    
    -(int) level {
        return level;
    }
    
    -(void) setLevel: (int) l {
        level = l;
    
        if ( level > 100 ) {
            // throw overflow
            NSException *e = [CupOverflowException
                exceptionWithName: @"CupOverflowException"
                reason: @"The level is above 100"
                userInfo: nil];
            @throw e;
        } else if ( level >= 50 ) {
            // throw warning
            NSException *e = [CupWarningException
                exceptionWithName: @"CupWarningException"
                reason: @"The level is above or at 50"
                userInfo: nil];
            @throw e;
        } else if ( level < 0 ) {
            // throw exception
            NSException *e = [NSException
                exceptionWithName: @"CupUnderflowException"
                reason: @"The level is below 0"
                userInfo: nil];
            @throw e;
        }
    }
    
    -(void) fill {
        [self setLevel: level + 10];
    }
    
    -(void) empty {
        [self setLevel: level - 10];
    }
    
    -(void) print {
        printf( "Cup level is: %i\n", level );
    }
    @end
  • main.m
    #import "Cup.h"
    #import "CupOverflowException.h"
    #import "CupWarningException.h"
    #import <Foundation/NSString.h>
    #import <Foundation/NSException.h>
    #import <Foundation/NSAutoreleasePool.h>
    #import <stdio.h>
    
    int main( int argc, const char *argv[] ) {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        Cup *cup = [[Cup alloc] init];
        int i;
    
        // this will work
        for ( i = 0; i < 4; i++ ) {
            [cup fill];
            [cup print];
        }
    
        // this will throw exceptions
        for ( i = 0; i < 7; i++ ) {
            @try {
                [cup fill];
            } @catch ( CupWarningException *e ) {
                printf( "%s: ", [[e name] cString] );
            } @catch ( CupOverflowException *e ) {
                printf( "%s: ", [[e name] cString] );
            } @finally {
                [cup print];
            }
        }
    
        // throw a generic exception
        @try {
            [cup setLevel: -1];
        } @catch ( NSException *e ) {
            printf( "%s: %s\n", [[e name] cString], [[e reason] cString] );
        }
    
        // free memory 
        [cup release];
        [pool release];
    }
  • output
    Cup level is: 10
    Cup level is: 20
    Cup level is: 30
    Cup level is: 40
    CupWarningException: Cup level is: 50
    CupWarningException: Cup level is: 60
    CupWarningException: Cup level is: 70
    CupWarningException: Cup level is: 80
    CupWarningException: Cup level is: 90
    CupWarningException: Cup level is: 100
    CupOverflowException: Cup level is: 110
    CupUnderflowException: The level is below 0
  • NSAutoreleasePool 是一個記憶體管理類別。
  • Exceptions(異常情況)的丟出不需要擴充(extend)NSException 物件,你可簡單的用 id 來代表它: @catch ( id e ) { ... }
  • 還有一個 finally 區塊,它的行為就像 Java 的異常處理方式,finally 區塊的內容保證會被呼叫。
  • Cup.m 裡的 @"CupOverflowException" 是一個 NSString 常數物件。在 Objective-C 中,@ 符號通常用來代表這是語言的衍生部分。C 語言形式的字串(C string)就像 C/C++ 一樣是 "String constant" 的形式,型別為 char *。

沒有留言:

張貼留言