Amazon.com Widgets Question about my string objects...
Welcome, Guest. Please login or register.
Did you miss your activation email?
May 18, 2013, 05:00:47 PM
Home Help Search chat Login Register   
News: Read this please.The Great Kangaroo Escape Looking for reviews of the 4th ed on Amazon!   Twitter:  @skochan
                     

+  Official Forum for Programming in Objective-C (the iPhone Programming Language) - Stephen Kochan
|-+  Old Stuff
| |-+  Chapter Study
| | |-+  Chapter 18 - Copying Objects
| | | |-+  Question about my string objects...
Pages: [1]   Go Down
Print
Author Topic: Question about my string objects...  (Read 570 times)
theOla
Newbie
*
Posts: 2






« on: April 05, 2011, 11:41:02 AM »

Hello.
I have run this program and everything seems to work fine, thus I did not append the output in this thread, to save space.
I have implemented the 'mutableCopyWithZone' in 'AddressBook' and 'copyWithZone' in 'AddressCard'.
Here´s the thing. I ran the program through the debugger with breakpoints to compare the addresses of the String objects in the AddressCards, that are stored in a Mutable Array (book). The string objects 'name' and 'email' are not deeply copied...
I even tried with alloc init in the 'copyWithZone' in AddressCard but that did not result in a deep copy of the
strings 'name' and 'email'.
I use 'copy' in the @property but maybe that only copies the strings memory addresses?
Can anyone try to point me in a better direction?


--------------------- The code:


------------------- AddressCard.h ---------------------------------------------

#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>



@interface AddressCard : NSObject <NSCopying>
{
   NSString *name;
   NSString *email;
}

@property (copy, nonatomic) NSString *name, *email;

- (id)copyWithZone:(NSZone *)zone;
- (BOOL)isEqual:(AddressCard *)theCard;
- (void)print;
- (void)setName:(NSString *)aName andEmail:(NSString *)anEmail;
- (NSComparisonResult)compareNames:(id)element;

@end


----------------------- AddressCard.m ----------------------------------------

#import "AddressCard.h"


@implementation AddressCard

@synthesize name, email;


- (id)copyWithZone:(NSZone *)zone
{
   AddressCard *newCard = [[[self class] allocWithZone:zone] init];
   newCard.name = [self name]; // Would some use of 'alloc' and 'init' create new string objects?
   newCard.email = [self email];

   return newCard;
}

- (void)dealloc
{
   [name release];
   [email release];
   [super dealloc];
}

- (void)setName:(NSString *)aName andEmail:(NSString *)anEmail
{
   self.name = aName;
   self.email = anEmail;
}

- (NSComparisonResult)compareNames:(id)element
{...}


- (BOOL)isEqual:(AddressCard *)theCard
{...}


- (void)print
{...}

@end


--------------------------- AddressBook.h --------------------------

#import <Foundation/NSObject.h>
#import <Foundation/NSArray.h>
#import "AddressCard.h"


@interface AddressBook : NSObject <NSMutableCopying>
{
   NSString *bookName;
   NSMutableArray *book;
}

@property (retain, nonatomic) NSString *bookName;
@property (copy, nonatomic) NSMutableArray *book;

- (id)initWithName:(NSString *)aName;
- (id)mutableCopyWithZone:(NSZone *)zone;
- (void)addCard:(AddressCard *)theCard;
- (void)removeCard:(AddressCard *)theCard;
- (int)entries;
- (AddressCard *)lookup:(NSString *)theName;
- (void)list;
- (void)sort;
- (void)dealloc;

@end

------------------------- AddressBook.m ------------------------------


#import "AddressBook.h"


@implementation AddressBook

@synthesize bookName;
@synthesize book;

- (id)initWithName:(NSString *)aName
{
   self = [super init];
   if(self)
   {
      bookName = [[NSString alloc] initWithString:aName];
      book = [[NSMutableArray alloc] init];
   }
   return self;
}

- (id)mutableCopyWithZone:(NSZone *)zone
{
   AddressBook *newBook = [[[self class] allocWithZone:zone] initWithName:@""];
   for(AddressCard *card in book)
   {
      AddressCard *newCard = [card copy];
      [newBook.book addObject:newCard];
      [newCard release]; // Retained by array...
   }
   return newBook;
}

- (void)dealloc
{
   [bookName release];
   [book release];
   [super dealloc];
}


- (void)addCard:(AddressCard *)theCard
{...}

- (void)removeCard:(AddressCard *)theCard
{...}

- (int)entries
{...}

- (void)list
{...}

- (void)sort
{...}


- (AddressCard *)lookup:(NSString *)theName
{...}

@end
Logged
skochan
Administrator
Hero Member
*****
Posts: 3103







« Reply #1 on: April 05, 2011, 02:55:23 PM »

When you make a copy of an immutable string object, the object is just retained.  You can't change it, so there's no need to make a new copy.  This is an optimization done by the copy method in the NSString class.

By the way, there is no mutable copy attribute for strings, only a copy attribute.

Cheers,

Steve
Logged
theOla
Newbie
*
Posts: 2






« Reply #2 on: April 05, 2011, 04:31:52 PM »

Thanks for your quick response!
Well, I could not let it go...so I made some changes in the code. Changed the members of AddressCard to Mutable Strings, added an 'initWithName andEmail'. Changed to 'mutableCopyWithZone' in AddressCard. Have not recieved any errors or warnings when building and testing all AddressBook methods...There are places
like: setName andEmail where NSStrings are expected but it seems fine...I guess because a NSMutableString inherits from NSString...!? And that it´s ok to store a pointer to a MutableString in a Immutable String variable.
Hope I´m correct on this.
I know that my 'solution' probably is 'much ado about nothing' but it fun to try...
If there is some problem lurking that I can not see, I would appreciate any comment.
regards
-Ola



------------------- AddressCard.h ---------------------------------------------

#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>



@interface AddressCard : NSObject <NSCopying>
{
   NSMutableString *name;  // changed these 2 variables
   NSMutableString *email;
}

@property (copy, nonatomic) NSString *name, *email;

- (id)initWithName:(NSString *)aName andEmail:(NSString *)anEmail;
- (id)mutableCopyWithZone:(NSZone *)zone;
- (BOOL)isEqual:(AddressCard *)theCard;
- (void)print;
- (void)setName:(NSString *)aName andEmail:(NSString *)anEmail;
- (NSComparisonResult)compareNames:(id)element;

@end


----------------------- AddressCard.m ----------------------------------------

#import "AddressCard.h"


@implementation AddressCard

@synthesize name, email;

- (id)initWithName:(NSString *)aName andEmail:(NSString *)anEmail  // ...added
{
   self = [super init];
   if(self)
   {
      if(name != nil)
         [name release];
      name = [[NSMutableString alloc] initWithString:aName];
      if(email != nil)
         [email release];
      email = [[NSMutableString alloc] initWithString:anEmail];
   }
   return self;
}

- (id)mutableCopyWithZone:(NSZone *)zone // changed
{
   AddressCard *newCard = [[[self class] allocWithZone:zone] initWithName:[self name] andEmail:[self email]];
   return newCard;
}

- (void)dealloc
{
   [name release];
   [email release];
   [super dealloc];
}

- (void)setName:(NSString *)aName andEmail:(NSString *)anEmail
{
   self.name = aName;
   self.email = anEmail;
}

- (NSComparisonResult)compareNames:(id)element
{...}


- (BOOL)isEqual:(AddressCard *)theCard
{...}


- (void)print
{...}

@end


--------------------------- AddressBook.h --------------------------

#import <Foundation/NSObject.h>
#import <Foundation/NSArray.h>
#import "AddressCard.h"


@interface AddressBook : NSObject <NSMutableCopying>
{
   NSString *bookName;
   NSMutableArray *book;
}

@property (retain, nonatomic) NSString *bookName;
@property (copy, nonatomic) NSMutableArray *book;

- (id)initWithName:(NSString *)aName;
- (id)mutableCopyWithZone:(NSZone *)zone;
- (void)addCard:(AddressCard *)theCard;
- (void)removeCard:(AddressCard *)theCard;
- (int)entries;
- (AddressCard *)lookup:(NSString *)theName;
- (void)list;
- (void)sort;
- (void)dealloc;

@end

------------------------- AddressBook.m ------------------------------


#import "AddressBook.h"


@implementation AddressBook

@synthesize bookName;
@synthesize book;

- (id)initWithName:(NSString *)aName
{
   self = [super init];
   if(self)
   {
      bookName = [[NSString alloc] initWithString:aName];
      book = [[NSMutableArray alloc] init];
   }
   return self;
}

- (id)mutableCopyWithZone:(NSZone *)zone
{
   AddressBook *newBook = [[[self class] allocWithZone:zone] initWithName:@""];
   for(AddressCard *card in book)
   {
      AddressCard *newCard = [card mutableCopy]; // changed to call mutableCopy
      [newBook.book addObject:newCard];
      [newCard release]; // Retained by array...
   }
   return newBook;
}

- (void)dealloc
{
   [bookName release];
   [book release];
   [super dealloc];
}


- (void)addCard:(AddressCard *)theCard
{...}

- (void)removeCard:(AddressCard *)theCard
{...}

- (int)entries
{...}

- (void)list
{...}

- (void)sort
{...}


- (AddressCard *)lookup:(NSString *)theName
{...}

@end
Logged
Pages: [1]   Go Up
Print
Jump to:  



Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Entire forum contents (c) 2009 classroomM.com. All rights reserved.