Created
October 3, 2009 07:39
-
-
Save sukima/200469 to your computer and use it in GitHub Desktop.
How to make a simple error reporter that is thread safe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* What I'm attempting to do is to init an object. I want that object to | |
* default to a value if there was an error. In other words because the object | |
* is a model it should not attempt to send a message to the user as this is | |
* the responsability of the view (or controller to decide what to do). So it | |
* needs a mechinism to commiunicate an error to the caller without ever | |
* throwing an exception. I'm using the errorString and weather it is nil or | |
* not. However it is possible that more than one thread accesses errorString | |
* and there for causing false positives. | |
* | |
* After carefull self review it dawned on me that the init method was thread | |
* safe. Because errorString is encapsulated as an instance variable and it is | |
* readonly there is no way for another thread to mutate this. If it were not | |
* readonly or if there was a mechinism to reset it then were would be worried | |
* about threads. | |
* | |
* Case in point the saveToFile: selector does just that. It resets the | |
* errorString. Now any thread could attempt to save and mutate errorString. | |
*/ | |
#import <Foundation/Foundation.h> | |
#import "SomeObject.h" | |
int main(int argc, char *argv[]) { | |
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; | |
SomeObject *myNewObject = [[SomeObject alloc] initWithFile:@"test.plist"]; | |
if (myNewObject.errorString != nil) | |
{ | |
// Warn the user | |
} | |
// Continue on with default values. | |
// Not thread safe | |
if ( [myNewObject saveToFile:@"foo.plist"] ) | |
{ | |
// We're good to go | |
} | |
else | |
{ | |
// There was an error | |
NSLog(@"Error Message: %@", myNewObject.errorString); | |
} | |
// Thread safe | |
NSString *errMsg = nil; | |
[myNewObject saveToFile:@"bar.plist" withErrorString:&errMsg]; | |
if ( errMsg != nil ) | |
{ | |
// We're good to go | |
} | |
else | |
{ | |
// There was an error | |
NSLog(@"Error Message: %@", errMsg); | |
} | |
[myNewObject release]; | |
[pool release]; | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
@interface SomeObject : NSObject { | |
NSString *errorString; | |
NSArray *testArray; | |
} | |
@property (nonatomic, readonly) NSString *errorString; | |
@property (nonatomic, readonly) NSArray *testArray; | |
- (id)initWithFile:(NSString *)filename; | |
- (BOOL)saveToFile:(NSString *)filename; | |
- (void)saveTofile:(NSString *)filename withErrorString:(NSString **)errMsg; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "SomeObject.h" | |
@implementation SomeObject | |
@synthesize errorString; | |
@synthesize testArray; | |
- (id)initWithFile:(NSString *)filename { | |
if (self = [super init]) | |
{ | |
// Do some file IO thing. | |
if ( YES ) // There was an error | |
{ | |
errorString = @"There was an error."; | |
// Set testArray to an empty array. (Fresh start) | |
testArray = [[[NSArray alloc] init] retain]; | |
} | |
else // All is good | |
{ | |
// Set testArray to something usefull based on file IO. | |
} | |
} | |
return self; | |
} | |
- (BOOL)saveToFile:(NSString *)filename { | |
// Clear errorString | |
[errorString release]; | |
errorString = nil; | |
// Attempt to save | |
if (YES) // Some thing went wrong | |
{ | |
errorString = @"There was an error."; | |
return NO; | |
} | |
// everything worked | |
return YES; | |
} | |
- (void)saveTofile:(NSString *)filename withErrorString:(NSString **)errMsg { | |
// Attempt to save file | |
if (YES) // Something went wrong | |
{ | |
*errMsg = @"There was an error"; | |
} | |
else | |
{ | |
*errMsg = nil; | |
} | |
} | |
- (void)dealloc { | |
[errorString release]; | |
[super dealloc]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment