-
異常情況(Exceptions)
- 注意:異常處理只有 Mac OS X 10.3 以上才支援。
- 基於 "Programming in Objective-C," Copyright © 2004 by Sams Publishing一書中的範例,並經過允許而刊載。
- 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 *。
e name 中的name函数是NSException中提供的 cString是NSString提供的