Hi all. I've got a situation where I need to reuse some Obj-C objects. Basically, I'm allocating and deallocating these very lightweight objects in staggering numbers, more or less continuously, for minutes to hours at a time, and so the performance overhead of the allocations really does add up. This app runs on a shared computing cluster where time is at a premium, so this level of optimization really is necessary. I am doing this in a retain/release world, not with GC. The objects in question are subclasses of my own direct subclass of NSObject.

So I'm keeping an "unused pool" of these objects, and when I'm done with an object I throw it into the pool, and when I need a new one I grab one from the pool. I do these operations with inline functions, so I can get a new object instance very quickly indeed. This works great, and I've been doing it for a while. Of course -init only gets called when the object is truly allocated, the first time around. From then on, I need to be careful to reuse the objects in a way that is safe. I just got bitten by a bug where I wasn't zeroing out an ivar that I should have zeroed out when I reused one of my objects, though. This has led me to consider doing a quick "bzero" call to zap all the ivars back to zero whenever I reuse an object, to be a bit more safe. It would entail a bit of a speed hit, but this bug I just found scared me a bit, so I want to at least try this idea and see how much of a speed penalty I would pay for the added safety.

The question is how to zero out the ivars correctly. I have the Class of the object I'm reusing, and I can do the math ahead of time once. But the class is not fixed at compile time; it depends upon choices the user makes at runtime. So I have to use the Objective-C runtime to find my ivar block and zero it out. The first ivar in the class is known, because it is defined by the common superclass of all of these objects; it's called "pedigree". So what I'm thinking of doing is:

1. individualIvarsOffset = ivar_getOffset(class_getInstanceVariable(individualClass, "pedigree"));

2. individualIvarsSize = class_getInstanceSize(individualClass) - individualIvarsOffset;

3. bzero(individual + individualIvarsOffset, individualIvarsSize);

Step one gets the offset of the known first instance variable. This seems safe to me as long as the ivar layout is guaranteed not be shuffled around arbitrarily; i.e. as long as variables occur in memory in the order in which they are declared in the header file. Is that a guarantee that Obj-C gives, or not?

Step two calculates the size of the ivars block that I own (i.e. not NSObject's ivars, which I certainly don't want to touch; just the ones for my subclasses) as the total instance size minus the offset of the known first instance variable. This seems safe given the same caveat as step one, plus the added caveat that no extra stuff can be added to the object's memory block at the end; everything from my first ivar to the end of the malloced block must belong to me. Again, I'm not sure if this is a guarantee Obj-C gives...?

Step 3 zeros out the ivars of object "individual" for reuse. This seems reasonable if the first two steps are reasonable. By the way, the ivars in question are all non-pointers; I'm not risking zeroing out pointers that should have been released or freed.

So, thoughts? Am I insane? Is the above scheme safe? Is there a better way? Thanks for any feedback!

(I think this question is appropriate for cocoa-dev rather than the objc-language list, but my apologies if I have posted to the wrong forum...)

Ben Haller
McGill University

_______________________________________________

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 arch...@mail-archive.com

Reply via email to