NSAutoreleasePool drain/dealloc

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

NSAutoreleasePool drain/dealloc

Ivan Vučica-2
Hi,

I was explaining refcounting and NSAutoreleasePool to someone, and I thought referencing GNUstep might be useful to explain the correct mental model of the behavior.

But I'm confused about -drain in the non-ARC implementation:

Won't equating drain and dealloc mean that pools will misbehave, and that after [pool drain], the incorrect pool will get populated (and later drained)?

Am I correctly interpreting that this happens? If so, is it correct that this happens?

NSAutoreleasePool * outerPool = [NSAutoreleasePool new];
[[NSObject new] autorelease]; // object 0 added to outerPool

NSAutoreleasePool * innerPool = [NSAutoreleasePool new];
[[NSObject new] autorelease]; // object 1 added to innerPool
[innerPool drain]; // object 1 released; outerPool is the closest pool
[[NSObject new] autorelease]; // object 2 added to outerPool
[innerPool release]; // object 2 released, object 0 released; new pool created as the closest pool

[outerPool release]; // no objects released; new pool created as the closest pool

Unless I am missing something, object 0 would be released early here?

_______________________________________________
Gnustep-dev mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/gnustep-dev
Reply | Threaded
Open this post in threaded view
|

Re: NSAutoreleasePool drain/dealloc

Richard Frith-Macdonald-9


> On 6 Mar 2018, at 17:08, Ivan Vučica <[hidden email]> wrote:
>
> Hi,
>
> I was explaining refcounting and NSAutoreleasePool to someone, and I thought referencing GNUstep might be useful to explain the correct mental model of the behavior.
>
> But I'm confused about -drain in the non-ARC implementation:
>   https://github.com/gnustep/libs-base/blob/b8185fa6c13172436c070ab3bf60b3f12bce433b/Source/NSAutoreleasePool.m#L546
>
> Won't equating drain and dealloc mean that pools will misbehave, and that after [pool drain], the incorrect pool will get populated (and later drained)?
>
> Am I correctly interpreting that this happens? If so, is it correct that this happens?
>
> NSAutoreleasePool * outerPool = [NSAutoreleasePool new];
> [[NSObject new] autorelease]; // object 0 added to outerPool
>
> NSAutoreleasePool * innerPool = [NSAutoreleasePool new];
> [[NSObject new] autorelease]; // object 1 added to innerPool
> [innerPool drain]; // object 1 released; outerPool is the closest pool
> [[NSObject new] autorelease]; // object 2 added to outerPool
> [innerPool release]; // object 2 released, object 0 released; new pool created as the closest pool
>
> [outerPool release]; // no objects released; new pool created as the closest pool
>
> Unless I am missing something, object 0 would be released early here?

According to Apple, the -drain method is a synonym for -release (or -dealloc since you don't retain autorelease pools).
So yes, if youi drain a pool the next time an object is autoreleased it goes into the parent pool of the one you drained.
Your code above should crash at the point where you call [innerPool release] since you are sending the -release message to a deallocated object.

I think the -drain method name is unintuitive.  To me it sounds like it ought to do the same as the gnustep-specific -emptyPool method (a more efficient equivalent to draining/releasing the pool and immediately creating a new one).



_______________________________________________
Gnustep-dev mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/gnustep-dev
Reply | Threaded
Open this post in threaded view
|

Re: NSAutoreleasePool drain/dealloc

Ivan Vučica-2

On Tue, Mar 6, 2018 at 5:24 PM, Richard Frith-Macdonald <[hidden email]> wrote:


According to Apple, the -drain method is a synonym for -release (or -dealloc since you don't retain autorelease pools).
So yes, if youi drain a pool the next time an object is autoreleased it goes into the parent pool of the one you drained.
Your code above should crash at the point where you call [innerPool release] since you are sending the -release message to a deallocated object.

Thank you! I guess I never read that part of the NSAutoreleasePool docs.
 
I think the -drain method name is unintuitive.  To me it sounds like it ought to do the same as the gnustep-specific -emptyPool method (a more efficient equivalent to draining/releasing the pool and immediately creating a new one).

That's what I assumed it was doing: releasing the members of the pool, while not releasing the pool itself.

Thank you!

_______________________________________________
Gnustep-dev mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/gnustep-dev
Reply | Threaded
Open this post in threaded view
|

Re: NSAutoreleasePool drain/dealloc

David Chisnall-7
In reply to this post by Richard Frith-Macdonald-9
On 6 Mar 2018, at 17:24, Richard Frith-Macdonald <[hidden email]> wrote:
>
> I think the -drain method name is unintuitive.  To me it sounds like it ought to do the same as the gnustep-specific -emptyPool method (a more efficient equivalent to draining/releasing the pool and immediately creating a new one).

-drain was introduced with GC, where -release was optimised away in either the compiler or the runtime and never delivered.  It allowed the GC implementation to use autorelease pools as a hint that there were a lot of short-lived objects to delete and have the same code work in non-GC mode.  ARC fixed this a lot better by introducing the @autoreleasepool syntax, and should be used in all new code.

David


_______________________________________________
Gnustep-dev mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/gnustep-dev