On Jun 6, 2008, at 4:24 PM, Ricky Sharp wrote:
On Jun 6, 2008, at 5:48 PM, Bill Bumgarner wrote:
On Jun 6, 2008, at 3:23 PM, Quincey Morris wrote:
In a GC-only app, I frequently use a pattern along these lines:

        NSData* data = <get it from somewhere>;
        const unsigned char* bytes = [data bytes];
        NSUInteger count = [data length];
        for (NSUInteger i = 0; i < count; i++)
                something = bytes [i];

In any case, you need to make sure that <data> stays alive throughout the entire lifespan of the bytes pointer. This is no different than in non-GC. If <data> were released sometime before the for loop were done, a similar crash would occur.
I'm a bit confused by this. In non-GC, data would not be released during the loop execution. Let's assume that it was autoreleased during the 'get it from somewhere'. It would only be actually released when execution returns to the main run loop; clearly after the entire loop above would be executed.

Sorry -- let me clarify. If the <data> was either released in a different thread or if <data> were explicitly released in the above code, then you would see the same crash. I didn't mean to imply that <data> would be released under non-GC without some explicit action being taken.

Under GC, the situation isn't quite so clear.

On Jun 6, 2008, at 4:27 PM, Quincey Morris wrote:
But the puzzling question is: how? Anything involving stack variables could potentially be optimized away. I could move the collectable object pointer into a global or instance variable, but that solution comes unglued as soon as I hit a case where the containing method is called recursively. I suppose a file static NSMutableSet temporarily holding collectable objects would work.

Good question. The easiest way is to force the compiler to maintain a viable reference to <data> on the stack throughout the code that is using gunk from inside of <data>. There is no way for the compiler or -- reliably, the collector, at this time-- to know that <bytes> is somehow connected to the storage of <data> and, thus, you need to make sure <data> stays alive.

The easiest way to do this is to simply to use data once after the for() loop:

        NSData* data = <get it from somewhere>;
        const unsigned char* bytes = [data bytes];
        NSUInteger count = [data length];
        for (NSUInteger i = 0; i < count; i++)
                something = bytes [i];
        [data self];

Yup. I don't particularly like it either. Fortunately, it is an uncommon case -- most of the objects in the AppKit/Foundation "just work". This kind of a problem arises when something leverages the C in Objective-C.

This is an area where the collector will hopefully be able to improve upon the coding experience in future releases.

b.bum

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________

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