Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful
Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful
- Subject: Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful
- From: John Engelhart <email@hidden>
- Date: Wed, 6 Feb 2008 20:48:46 -0500
On Feb 6, 2008, at 10:45 AM, glenn andreas wrote:
On Feb 6, 2008, at 3:39 AM, John Engelhart wrote:
On Feb 5, 2008, at 7:40 AM, Alastair Houghton wrote:
On 5 Feb 2008, at 00:14, John Engelhart wrote:
I had such high hopes for Cocoa's GC system because once you're
spoiled by GC, it's hard to go back.
Unfortunately, the 4-5 months of time I've put in on Leopard's GC
system has not been nearly as pleasant. It has been outright
frustrating, and it's reached the point where I consider the
system untenable.
Honestly, this point has now been answered over and over.
I think it comes down to the fact that you have failed to
appreciate that Cocoa GC is designed for easy use with *OBJECTS*.
If you're using it with objects, it "just works".
You misunderstand what Objective C is, and how it works. "Objects"
is synonymous for "Structs".
If that were true, you'd be able to declare objects as local
variables (as opposed to as pointers to structures):
NSPoint aPoint; // <-- NSPoint = struct, legal
NSString aString; // <-- NSString = object, Illegal
Surprisingly, you can actually do this. It requires some contortions
and manual initiation, but the end result ends up being identical to
what "NSString aString" would have been:
[johne@LAPTOP_10_5] /tmp% cat tst.m
#import <Foundation/Foundation.h>
int main(int argc, char **argv) {
NSObject *stackObject = NULL;
stackObject = alloca(sizeof(stackObject));
memset(stackObject, 0, sizeof(NSObject));
stackObject->isa = [NSObject class];
NSLog(@"stackObject: %@", stackObject);
}
[johne@LAPTOP_10_5] /tmp% gcc -framework Foundation -o tst tst.m
tst.m: In function 'main':
tst.m:7: warning: instance variable 'isa' is @protected; this will be
a hard error in the future
[johne@LAPTOP_10_5] /tmp% ./tst
2008-02-06 20:17:16.306 tst[18320:807] stackObject: <NSObject:
0xbffff380>
As the address clearly shows, this is an object on the stack.
Although I have had to manually initialize the object, it is exactly,
or very close to, what "NSObject stackObject" would have created.
This is generally a bad idea to do in practice as the object is
"deallocated" as soon as the frame pops. But because it's on the
stack there is no way to ensure something along the lines of
"release / dealloc" happens to make sure that any of the resources the
object may have created/acquired are released... this is generally a
bad idea, and why it is disallowed in practice.
As you can see, and the code clearly demonstrates, my original
assertion stands.
(yes, at one time there was an attempt to add support for that, but
it didn't survive).
Yes, the machinery to arrange for stack objects to have a chance to
"dealloc" when the stack frame pops is non-trivial. But, as shown
above, you can do it, but it's really not a good idea.
Structures don't have "magic invisible members":
@interface Foo {
}
@end
Foo *aFoo;
NSLog(@"Foo is a %@", aFoo->isa);
Notice how there is an "isa" member that is automatically put there,
not unlike the way that a C++ object might have a vtable (or other
internal plumbing for multiple inheritance).
struct FooDef { @defs(Foo) } *aFoo;
aFoo->isa;
You're right, structs don't have magic invisible members. The @defs()
directive allows you to "copy" the ivars from the @interface
declaration.
It's instructive to look at objc/objc.h, where we find the following:
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;
typedef struct objc_selector *SEL;
typedef id (*IMP)(id, SEL, ...);
As you can see, it's very clear where "isa" comes from. Subclassing
an object has the effect of "pasting" your ivar declarations at the
end of the class you're inheriting from, and forms the cause of
"fragile classes" since a struct effectively becomes pointer + offset,
and changing a struct requires recompiling code to update those offsets.
So, no, there are no magic invisible members. Furthermore:
typedef id (*IMP)(id, SEL, ...);
Is a function prototype declaration. You're probably familiar with
it, as the following makes a bit more clear:
typedef id (*IMP)(id self, SEL _cmd, ...);
This is where self and _cmd come from. Nothing hidden. It's pure
ANSI-C, with a bit of syntactic sugar that automates common tasks like
object inheritance, automatic scoping of variables from self, and a
clever key (selector) / value (pointer to a function) dynamic run time
system known as "message dispatching."
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden