Re: Convenience Methods
Re: Convenience Methods
- Subject: Re: Convenience Methods
- From: Erik Buck <email@hidden>
- Date: Wed, 26 Sep 2007 22:22:15 -0400
The following simple example illustrates the reality of writing an
algorithm that relies on a supposedly immutable object actually being
immutable.
Here's the output so you don't have to built it yourself to find out
the stunning conclusion:
2007-09-26 22:21:35.570 TestMutability2[1510] This algorithm depends
on an object that claims to be an NSArray really being immutable
2007-09-26 22:21:35.571 TestMutability2[1510] Supposedly immutable
widgetsArray has class: NSCFArray
2007-09-26 22:21:35.572 TestMutability2[1510] widgetsArray contents:
(A, B, C)
2007-09-26 22:21:35.572 TestMutability2[1510] widgetsArray contents:
(A, B, C)
2007-09-26 22:21:35.572 TestMutability2[1510] widgetsArray contents:
(A, C)
2007-09-26 22:21:35.572 TestMutability2[1510] Opps! The immutable
widgetsArray changed behind my back.
2007-09-26 22:21:35.573 TestMutability2[1510] This algorithm
addresses the reality that something claiming to be immutable might
not really be immutable. You must always make a copy!
2007-09-26 22:21:35.588 TestMutability2[1510] My copy of widgetsArray
has class: NSCFArray
2007-09-26 22:21:35.588 TestMutability2[1510] copy of widgetsArray
contents: (A, B, C)
2007-09-26 22:21:35.588 TestMutability2[1510] copy of widgetsArray
contents: (A, B, C)
2007-09-26 22:21:35.589 TestMutability2[1510] copy of widgetsArray
contents: (A, B, C)
Here's the program:
#import <Foundation/Foundation.h>
@interface MYWidgetManager : NSObject
{
NSMutableArray *widgetArray;
}
- (id)init;
- (void)dealloc;
- (NSArray *)widgets;
- (void)removeWidget:(id)aWidget;
@end
int main (int argc, const char * argv[])
{
// Oh dear! My algorithm tries to avoid a copy because
widgetsArray is supposed to be immutable
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSLog(@"This algorithm depends on an object that claims to be
an NSArray really being immutable");
MYWidgetManager *testManager = [[[MYWidgetManager alloc]
init] autorelease];
NSArray *widgetsArray = [testManager widgets];
int i;
const int countOfWidgetsArray = [widgetsArray count];
NSLog(@"Supposedly immutable widgetsArray has class: %@",
[widgetsArray class]);
NS_DURING
for(i = 0; i < countOfWidgetsArray; i++)
{
NSLog(@"widgetsArray contents: %@", widgetsArray);
if(NSOrderedSame == [@"B" compare:[widgetsArray
objectAtIndex:i]])
{
[testManager removeWidget:[widgetsArray objectAtIndex:i]];
}
}
NS_HANDLER
NSLog(@"Opps! The immutable widgetsArray changed behind my
back.");
NS_ENDHANDLER
[pool release];
}
// What happens if I make a copy ?
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSLog(@"This algorithm addresses the reality that something
claiming to be immutable might not really be immutable. You must
always make a copy!");
MYWidgetManager *testManager = [[[MYWidgetManager alloc]
init] autorelease];
NSArray *widgetsArray = [[[testManager widgets]
copy] autorelease];
int i;
const int countOfWidgetsArray = [widgetsArray count];
NSLog(@"My copy of widgetsArray has class: %@", [widgetsArray
class]);
for(i = 0; i < countOfWidgetsArray; i++)
{
NSLog(@"copy of widgetsArray contents: %@", widgetsArray);
if(NSOrderedSame == [@"B" compare:[widgetsArray
objectAtIndex:i]])
{
[testManager removeWidget:[widgetsArray objectAtIndex:i]];
}
}
[pool release];
}
return 0;
}
@implementation MYWidgetManager
- (id)init
{
if(nil != (self = [super init]))
{
widgetArray = [[NSMutableArray alloc] initWithObjects:@"A",
@"B", @"C", nil];
}
return self;
}
- (void)dealloc
{
[widgetArray release];
[super dealloc];
}
- (NSArray *)widgets
{
return widgetArray;
}
- (void)removeWidget:(id)aWidget
{
[widgetArray removeObject:aWidget];
}
@end
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden