Re: half-initialized objects during decoding (Re: Persistance)
Re: half-initialized objects during decoding (Re: Persistance)
- Subject: Re: half-initialized objects during decoding (Re: Persistance)
- From: "Marco Scheurer" <email@hidden>
- Date: Thu, 11 Oct 2001 14:47:58 +0200
On Wed, 10 Oct 2001 13:21:01 -0700
Chris Kane <email@hidden> wrote:
>
The 'half-initialized object' problems I was referring to
>
I describe below. [...]
It seems to me that you can force yourself into the same
situation in other cases:
@implementation A
- init
{
...
b = [[B alloc] initWithA:self];
...
}
@end
@implementation B
- initWithA:(A *) anA
{
...
x = [anA someValue];
...
}
@end
If anA is half-initialized, x's value could be junk. I think
that in that case it is obviously the programmer's
responsibility not to create this kind of coupling or to
order messages so that "it works". Why should the
unarchiving situation be different?
>
One historical insidious manifestation of this problem
>
is when an object A implements internal reference
>
counting in one of its fields. During decoding, B gets
>
a reference to A (with -decodeObject) and retains it,
>
invoking -retain on the half-initialized A.
>
A's initWithCoder: proceeds, and at some point sets the
>
ref count field to 0 (initializing it), but this blows
>
away B's retain (and anybody else's).
Why is initWithCoder assuming that the retain count should
be initialized to 0? Is this how NSUnarchiver returns
autoreleased objects? In that case, something like x = [[X
alloc] initWithCoder:aCoder]; is also very wrong, since
everybody would assume that the retain count is 1.
I would have imagined that initializing a retain count (to 1
rather than 0) should be left to allocWithZone, and that
init... methods should leave it untouched. This would be
coherent with all the doc I've seen about alloc and copy,
statements like (in Object Ownership and Disposal): "If you
create an object (using alloc or allocWithZone:) or copy an
object (using copy, copyWithZone:, mutableCopy, or
mutableCopyWithZone:), you alone are responsible for
releasing it. If you didn't directly create or copy the
object, you don't own it and shouldn't release it." This
cannot work if init methods mess with retain counts.
And not messing with the retain count in initWithCoder would
remove that insidious hitorical problem.
Or am I missing something?
Marco Scheurer
Sen:te, Lausanne, Switzerland
http://www.sente.ch