• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: help needed with OO concepts when copying
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: help needed with OO concepts when copying


  • Subject: Re: help needed with OO concepts when copying
  • From: Chris Giordano <email@hidden>
  • Date: Tue, 11 Feb 2003 17:05:08 -0500

Denis,

Actually, you are making a copy of the array (or two when you copy the array you send with the setBlock: message) . Unfortunately, you're not also copying the elements of the array, so all two (or three) arrays contain the same set of objects. That may not make things clearer. Let me try to elaborate.

What you've got is a bunch of objects (your blocks). These objects are put into your first array. This first array is essentially a list of pointers to your objects. When you create your second array by just copying the first array, what you are doing is creating another list of pointers to your original objects. The objects in the two arrays are actually the same objects, so changing an object via one array will also cause references to the object via the second array to have this change. You still only have one set of objects (blocks).

In C terms, you're doing something like the following:

int data = 10;
int *first = &data;
int *second = first;

You now have to pointers that point at the same data. Any changes to data will be reflected in both first and second. What you want to do is copy the contents of data and put it into a new integer. That's not what you're doing in your code.

What you need to do is to copy the items as well as the array. You can do this manually by creating an empty second array, iterating over the first one and inserting copies of each object into the second one. You can also try using some of the methods that Cocoa provides for you. I haven't tried it myself, but the method initWithArray:copyItems: of NSArray would probably do the trick (see <http://developer.apple.com/techpubs/macosx/Cocoa/Reference/Foundation/ ObjC_classic/Classes/NSArray.html#BCIFDAHF> for details).

So, in your setBlocks: method (which has a few other issues -- you're allocating myBlocks, and then leaking that one when you use "myBlocks = [newBlocks copy]"), you'd want to do something like the following.

- (void)setBlocks: (NSMutableArray *) newBlocks
{
if (blocks == newBlocks) return; // save yourself some work in case they are the same

NSMutableArray * oldBlocks = blocks;
blocks = [[NSMutableArray alloc] initWithArray:newBlocks copyItems:YES];
[oldBlocks release];
}

After this method is performed, blocks will point to a new array with objects that are copies of those in the original array. Assuming that your blocks are such that they will produce a different object when sent a "copyWithZone:" message, you should have what you need.

Hope this helps.

chris


On Tuesday, February 11, 2003, at 02:55 PM, Denis Stanton wrote:

Hi

I hope someone can help me out with a gap in my understanding of object
concepts. I'm trying to make a copy of an MSMutableArray, so that I
have two arrays. I then try and modify the text contents of one of the
arrays and I see the same changes occur in the other array. This tells
me that rather than making two arrays all I am doing is making two
references to the same one. I have spent many hours trying to figure
out this copying thing, but I'm stumped. How do I make a separate copy
of an array with the same initial values as the original, but otherwise
independent of it?

In my app I have an NSMutableArray named reports.

NSMutableArray *reports;
int reportIndex;

reports = [[NSMutableArray alloc] init];

Each row of this array defines the format for a report my app will
produce. The rows are defined by the Report class.
A Report instance contains three items, a report name, report title and
an array defining the items to appear in the report. This array is
called blocks and contains instances of Block.

@interface Report : NSObject <NSCoding> {
NSString *name;
NSString *title;
NSMutableArray *blocks;
}
- (NSString *)name;
- (void)setName: (NSString *)value;
- (NSString *)title;
- (void)setTitle: (NSString *)value;
- (NSMutableArray *)blocks;
- (void)setBlocks: (NSMutableArray *)newBlocks;

@end

@implementation Report
- (void)setBlocks: (NSMutableArray *) newBlocks {
[blocks autorelease];
NSMutableArray *myBlocks = [[NSMutableArray alloc] init];
myBlocks = [newBlocks copy];
blocks = myBlocks;
}


The problem comes when I want to define a new report. The chances are
that a new report will resemble an existing one, with some changes, so
I thought the best thing to offer the user is a duplicate button which
adds another row to the reports array, copying a selected row. The new
row could then be modified. This works fine for the name and title
fields, but not for the blocks array. When I think I'm making a copy of
the blocks array I am actually just making more references to it.

- (void)tableViewSelectionDidChange: (NSNotification *)aNotification {
reportIndex = [tableView selectedRow];
}

- (IBAction)duplicateReport:(id)sender
{
Report *report = [[Report alloc] init];
[report setName: [[reports objectAtIndex: reportIndex] name]];
[report setTitle: [[reports objectAtIndex: reportIndex] title]];
[reports setBlocks : [[reports objectAtIndex: reportIndex] blocks]];

[reports insertObject: report atIndex: reportIndex];

[tableView reloadData];
}

I thought the requirement was to set the blocks array in the new report
row to be a copy of the blocks array in the existing report row, but
this doesn;' seem to help.
Can anybody see what I'm missing here?
I tried adding a copy request, but that doesn't seem to make any
difference

[reports setBlocks : [[[reports objectAtIndex: reportIndex] blocks]
copy]];

Thanks in advance for any advice.

Denis Stanton
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.

  • Follow-Ups:
    • Re: help needed with OO concepts when copying
      • From: Denis Stanton <email@hidden>
References: 
 >help needed with OO concepts when copying (From: Denis Stanton <email@hidden>)

  • Prev by Date: Re: how is C often used in Cocoa, if at all?
  • Next by Date: Re: how is C often used in Cocoa, if at all?
  • Previous by thread: Re: help needed with OO concepts when copying
  • Next by thread: Re: help needed with OO concepts when copying
  • Index(es):
    • Date
    • Thread