On May 7, 2009, at 12:27 AM, Marcel Weiher wrote:

OK, quiz time: the reason for NSMutableString to relinquish ownership is to (a) release the object (b) allow someone else to take ownership?

Answer: always (a), sometimes (b), and sometimes (c).

EXACTLY. Autorelease allows ownership transfer from called methods to occur without thrusting ownership on those that don't want it.

That's one use, anyway.

Retain/autorelease is the preferred way of implementing a getter method.

Some claim, many dispute.

Heh, I'm inclined to think that in reality, "some" and "many" are reversed.

Wether it is 'preferred' or not, however, is irrelevant to what I said: it is not required and thus there is no need to do this. Alas, misunderstandings such as yours are exactly the sort of thing I foresaw when I co-wrote "Autoreleasing accessors considered harmful"

Nothing is 'required'. There's no rule that says you can't write a crashy app, for example. Many people do. The question is about best practice.

This is not a debate. This is me explaining to you how this stuff works.

No, this is a debate. Let's keep it professional, please, no posturing.

Now, in this particular case I don't think it's acceptable to take the dogmatic attitude that the caller has the right to do whatever it wants with the objects, because we have a bit of an unusual situation here, involving a weak reference. The delegating object cannot have a strong reference to its delegate, otherwise you'd have a retain cycle. The rules of memory management that apply to strong references don't fully apply here, we need to be very careful.

Yes, we need to be somewhat careful, which is why don't do crazy stuff like releasing an object from within a delegate method.

Of course, nobody is suggesting release. The issue here is autorelease.

You'll end up writing crazy, inelegant, hard to read, hard to understand code.

What's crazy and weird about:

        id parser = [NSXMLParser alloc] initWithData:myData];
        [parser parse];
        [parser release];

?

Trying to deallocate an object from within its delegate, now that's weird and crazy, as numerous people have pointed out to you.

1) I never said you should deallocate an object from within its delegate method. I said that you should write your object's code so that it's safe to call autorelease from within the delegate method -- which means that it would not be deallocated from within its delegate method.

2) Who are these 'numerous' people you're talking about. I've been debating with you. Stephen J. Butler made one reply to me. That's two.

3) As I said below, "It's of course somewhat easier to work around this problem given the API of NSXMLParser, but you can't generalize to all delegate methods based on NSXMLParser."

It makes much more sense to code in a more straightforward way, for the common case, and if an object is going to do weird memory things with its delegate, it needs to take responsibility for not causing crashes and other problems. In this case, the delegating object knows when it's going to wrap the delegate calls in an autorelease pool, so it can easily account for that, whereas the delegate itself has no idea and would have a very hard time accounting for that. How does the delegate know when exactly in the future it's safe to actually release or autorelease its instance variable? You might say wait until dealloc, but it may need to re- use that instance variable for another object.

I'm not sure I understand what the alternative is that you're suggesting. Short of dealloc, when exactly is it safe for the delegate to relinquish ownership of the object?

The delegate never has ownership of the object.

Usually the delegate is the owner. That is, the owner allocates the object and sets itself as the delegate.

According to your argument, you can't even assume it's safe in some kind of "didFinish" delegate method, because the object could still do weird stuff after calling didFinish on the delegate.

The only thing that would be weird here would be if the caller were actually deallocated when it returns from sending the "didFinish" message. Look at the following.

It's of course somewhat easier to work around this problem given the API of NSXMLParser, but you can't generalize to all delegate methods based on NSXMLParser. What about more async delegate like NSURLConnection?

It is the *owner* of the object that releases it, not the delegate.

As above, usually they're the one and the same.

The claim by Stephen J. Butler was, "it's never safe to release/ autorelease an object from inside one of it's delegate calls." I agree about release, but not about autorelease. And NSXMLParser is not a good example to generalize upon, because as we see with your code fragment, you don't even need delegate methods to know when it's done.

I'm still waiting to hear a solution for the fully async cases.

_______________________________________________

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