- 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];
}
- outputCup 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 *。
沒有留言:
張貼留言