Well i started out making a immutable copy method that worked like a mutable one with synthesized setters and getters and ended up with this, is this the correct way to do subclassing & mutable/immutable variants or have i nested myself too deep with it all.
I slammed the interface and implementation code into the header files, to make it more clean when posting it up here. I went through the code and checked for leaks and it should be fine.
Please give any thoughts on it.
While doing all this i figured out that the code below works, if someone could explain why that would be super

NSString *iStr = [NSString stringWithString:@"i"];
NSMutableString *mStr = [NSMutableString stringWithString:@"m"];
id idVar;
iStr = [mStr mutableCopy];
idVar = iStr;
[idVar setString:@"something else"];
NSLog(@"%@",iStr);
Here's for the exercise:
AdressBook.h#import <Foundation/Foundation.h>
#import "AdressCard.h"
@class MutableAdressBook;
@interface AdressBook : NSObject <NSCopying, NSMutableCopying> {
NSString * bookName;
NSMutableArray * book;
}
-(id)initWithName: (NSString*)name andBook:(NSArray*)book;
-(int)entries;
-(void)list;
-(void)dealloc;
-(AdressCard*)lookup:(NSString*)name;
-(NSString*)bookName;
-(NSArray*)book;
@end
@implementation AdressBook
-(NSArray*)book
{
return [[book copy] autorelease];
}
-(NSString*)bookName
{
return bookName;
}
-(id)copyWithZone:(NSZone *)zone
{
AdressBook *newBook = [[AdressBook allocWithZone:zone] initWithName:bookName andBook:book];
return newBook;
}
-(id)mutableCopyWithZone:(NSZone *)zone
{
MutableAdressBook *newBook = [[MutableAdressBook allocWithZone:zone] initWithName:bookName andBook:book];
return newBook;
}
-(void)dealloc
{
[book release];
[super dealloc];
}
-(id)initWithName:(NSString *)name andBook:(NSArray*)array
{
self = [super init];
if (self)
{
bookName = [name copy];
book = [array copy];
}
return self;
}
-(id)initWithName:(NSString *)name
{
self = [super init];
if (self)
{
bookName = [name copy];
book = [[NSArray alloc] init];
}
return self;
}
-(int)entries
{
return [book count];
}
-(void)list
{
NSLog(@"========== Contents of: %@ ============",bookName);
for (AdressCard *theCard in book)
{
NSLog(@"%-20s %-32s",[theCard.name UTF8String],[theCard.email UTF8String]);
}
NSLog(@"=======================================");
}
-(AdressCard*)lookup:(NSString *)name
{
for (AdressCard *nextCard in book)
{
if ([[nextCard name] caseInsensitiveCompare:name] == NSOrderedSame)
return [[nextCard mutableCopy] autorelease];
}
return nil;
}
@end
MutableAdressBook.h#import <Foundation/Foundation.h>
#import "AdressBook.h"
@interface MutableAdressBook : AdressBook {
}
-(id)initWithName: (NSString*)name;
-(id)initWithName: (NSString*)name andBook:(NSMutableArray*)book;
-(void)addCard: (AdressCard*)theCard;
-(void)dealloc;
-(void)removeCard:(AdressCard*)theCard;
-(void)sort;
-(void)setBookName:(NSString *)newName;
-(void)setBook:(NSMutableArray *)newBook;
-(NSString*)bookName;
-(NSMutableArray*)book;
@end
@implementation MutableAdressBook
-(NSMutableArray*)book
{
return [[book mutableCopy] autorelease];
}
-(void)setBook:(NSMutableArray*)newBook;
{
if (newBook != book)
[book release];
book = [newBook mutableCopy];
}
-(NSString*)bookName
{
return bookName;
}
-(void)setBookName:(NSString*)newName
{
bookName = [newName copy];
}
-(id)mutableCopyWithZone:(NSZone *)zone
{
MutableAdressBook *newBook = [[MutableAdressBook allocWithZone:zone] initWithName:bookName andBook:book];
return newBook;
}
-(id)initWithName:(NSString *)name andBook:(NSMutableArray*)array
{
self = [super init];
if (self)
{
bookName = [name copy];
book = [array mutableCopy];
}
return self;
}
-(void)dealloc
{
[book release];
[super dealloc];
}
-(id)initWithName:(NSString *)name
{
self = [super init];
if (self)
{
bookName = [name copy];
book = [[NSMutableArray alloc] init];
}
return self;
}
-(void)addCard:(AdressCard *)theCard
{
[book addObject:theCard];
}
-(int)entries
{
return [book count];
}
-(void)list
{
NSLog(@"========== Contents of: %@ ============",bookName);
for (AdressCard *theCard in book)
{
NSLog(@"%-20s %-32s",[theCard.name UTF8String],[theCard.email UTF8String]);
}
NSLog(@"=======================================");
}
-(AdressCard*)lookup:(NSString *)name
{
for (AdressCard *nextCard in book)
{
if ([[nextCard name] caseInsensitiveCompare:name] == NSOrderedSame)
return [[nextCard copy] autorelease];
}
return nil;
}
-(void)removeCard:(AdressCard *)theCard
{
[book removeObjectIdenticalTo:theCard];
}
-(void)sort
{
[book sortUsingSelector:@selector(compareNames:)];
}
@end
Main.m#import <Foundation/Foundation.h>
#import "MutableAdressBook.h"
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
MutableAdressBook *book1 = [[MutableAdressBook alloc] initWithName:@"book1"];
AdressBook *book2;
MutableAdressBook *book3;
AdressCard *card1 = [[AdressCard alloc] init];
AdressCard *card2 = [[AdressCard alloc] init];
//assign info to cards
[card1 setName:[NSMutableString stringWithString:@"Lars eriksson"] andEmail:@"lars.eriksson@someemail.com"];
[card2 setName:@"Nisse Andersson" andEmail:@"nisse.andersson@someemail.com"];
//add stuff to book1
[book1 addCard:card1];
[book1 addCard:card2];
book2 = [book1 copy];
book3 = [book2 mutableCopy];
[book1 removeCard:card1];
[book3 removeCard:card2];
[book1 list];
[book2 list];
[book3 list];
[card1 release];
[card2 release];
[book1 release];
[book2 release];
[book3 release];
[pool drain];
return 0;
}