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