In article <fmds24$cpr$1@[EMAIL PROTECTED]
>, ActiveMan <basurero@[EMAIL PROTECTED]
>
wrote:
> 2) The compiler allows to create __strong and __weak global object
> pointers without complaint, but in both cases the related object
> receives the finalize method call when the variable is nilled, that is:
>
> __weak Point* pp; // Global variable
>
> int main (int argc, const char * argv[]) {
> pp = [[Point alloc] initWithX:1 y:1];
> pp = nil;
> [[NSGarbageCollector defaultCollector] collectExhaustively]; //
> Executes finalize over pp
> return 0;
> }
>
> This is not congruent with the semantics of __weak that the
> do***entation provides because the collector must not finalize __weak
> pointers.
Where did you get that idea from? I think you do not completely
understand the meaning of 'weak' and 'strong' references.
Garbage collection does not affect the life cycles of variables, but of
the data any pointers point to. For example, in plain C:
int f()
{
int * p = new int[4];
}
it is not the memory for variable p (the reference to the allocated
object) that leaks, but the memory that "new int[ 4]" allocated.
The difference between weak and strong pointers is:
- an allocated object is reachable as long as at least one (strong or
weak) pointer to it is reachable.
- the garbage collector can finalize and collect an allocated object as
soon as there are no strong references to that object.
See
<http://developer.apple.com/do***entation/Cocoa/Conceptual/GarbageCollect
ion/Articles/gcEssentials.html#//apple_ref/doc/uid/TP40002452-SW3>
> __strong int i=4; // No warning
I do not completely understand why the compiler would allow this. If I
is not a reference, the term 'strong' does not make sense for it.
> __weak Point* p = [[Point alloc] init]; // Warning
"__weak" allows the garbage collector to collect the Point. When the
garbage collector does that, it should set p to nil.
I guess that the compiler disallows this because:
- it is hard for the runtime to detect when p goes out of scope.
- it does not make much sense to use __weak locals. Having one would say
"I need to use a Point in this function, but feel free to take it away
if you need memory".
- any implementation allowing this would be very slow.
Herre is about the simplest example I could come up with:
__weak NSString * weakPointer;
__strong NSString * strongPointer;
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
weakPointer = [[NSString alloc] initWithCString: "weak"];
strongPointer = [[NSString alloc] initWithCString: "strong"];
NSLog(@[EMAIL PROTECTED]
"weakPointer = %d ('%@[EMAIL PROTECTED]
')", (int)weakPointer, weakPointer);
NSLog(@[EMAIL PROTECTED]
"strongPointer = %d ('%@[EMAIL PROTECTED]
')", (int)strongPointer,
strongPointer);
[[NSGarbageCollector defaultCollector] collectExhaustively];
NSLog(@[EMAIL PROTECTED]
"weakPointer = %d ('%@[EMAIL PROTECTED]
')", (int)weakPointer, weakPointer);
NSLog(@[EMAIL PROTECTED]
"strongPointer = %d ('%@[EMAIL PROTECTED]
')", (int)strongPointer,
strongPointer);
[pool drain];
return EXIT_SUCCESS;
}
Typical output is:
weakPointer = 16848992 ('weak')
strongPointer = 16849008 ('strong')
weakPointer = 0 ('(null)')
strongPointer = 16849008 ('strong')
So, the weak reference got garbage collected; the strong one did not.
Reinder


|