On Jun 7, 2008, at 8:18 AM, Michael Ash wrote:

It *does* do this. The error is not in the GC, but rather in the
assumption that "declared in the current scope" is equivalent to "is
on the stack frame". This assumption is not valid. The fact that you
can't make this assumption is extremely inconvenient for the situation
being discussed, but that doesn't mean that it's not behaving as
documented.


I did a double-take myself during the start of this thread and took a while for it all to sink in. I completely agree with what Michael here and others have been pointing out. Perhaps the following diagram and comparison to other code will be helpful to others:

- (void)foo
{
[1]    NSData* data = [...];
[2]    const unsigned char* bytes = [data bytes];
[3]    while (condition)
[4]        do work on bytes
[5]    remaining code which does not operate on either data or bytes
}

Below, let |----| represent a short span of time that covers a particular line of code. Fill it with # to denote timeframes where 'data' is valid (i.e. cannot be collected). Fill it with $ to denote timeframes where the GC thread can collect data.

                1     2     3     4     5
Main Thread: |#####|#####|-----|-----|-----|

GC Thread  : |-----|-----|$$$$$|$$$$$|$$$$$|


- (void)bar
{
[1]    NSData* data = [...];
[2]    const unsigned char* bytes = [data bytes];
[3]    while (condition)
[4]        do work on bytes
[5]    [data self];
[6]    remaining code which does not operate on either data or bytes
}

                1     2     3     4     5     6
Main Thread: |#####|#####|#####|#####|#####|-----|

GC Thread  : |-----|-----|-----|-----|-----|$$$$$|


You can thus see that for each method, the GC thread can collect 'data' at a point prior to the last statement. Sometimes, as is 'foo', this can be quite 'early'.



I haven't yet moved my app to GC since it's still baselined to 10.4. When I do migrate, I will have to tackle this specific NSData issue. For my needs, I'm hoping that a simple copy to a well-formed buffer will suffice. Performance is not an issue and quantity of bytes is always small.

I will hope though that within the context of say memcpy, that the GC thread could not collect data. For example, the following should be safe:

memcpy(myLocalGCAwareBuffer, [data bytes], numberOfBytes);


Finally, I think that usages of NSMutableData may also be a bit tricky. In my case I'll probably just obtain a copy of its bytes, manipulate them and then copy the result back in. Sort of ironic though in that the inner pointer would have been valid anyhow in such blocks of code (the NSMutableData instance would be around between the get and subsequent set of its bytes):

NSMutableData* data = [...];
const unsigned char* bytes = [data bytes];
operate on copy of bytes in GC-aware buffer
[data replaceBytesInRange:...];

___________________________________________________________
Ricky A. Sharp         mailto:[EMAIL PROTECTED]
Instant Interactive(tm)   http://www.instantinteractive.com

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to