Re: Who owns a child view controller?

2017-07-14 Thread Quincey Morris
On Jul 14, 2017, at 11:43 , Greg Parker  wrote:
> 
> it would be deallocated after the callee relinquishes ownership and before 
> the caller can retake ownership

See? I tried to reason about retain counts, and got it wrong. :)


___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-14 Thread Greg Parker

> On Jul 14, 2017, at 10:59 AM, Quincey Morris 
>  wrote:
> 
>> On Jul 14, 2017, at 03:50 , Jeremy Hughes  
>> wrote:
>> 
>> I’m still not entirely clear on when autorelease pools are used in Swift.
> 
> I think about it this way:
> 
> Autorelease is the run-time feature that provides an atomic return.
> 
> There is no such thing as an “atomic” return naturally built into in any of 
> the run-time environments using ARC (or MRC). That is, if a function result 
> is a reference-counted object, there is nothing that naturally prevents the 
> reference count from changing during the short window of mis-opportunity from 
> when a release occurs just before a callee returns, and the caller gets an 
> opportunity to retain the reference. That’s the price of multi-threading.

This description applies even in the absence of threads. There is always a 
"window of mis-opportunity" between the callee's last release and the caller's 
first retain. If this is the only reference to the object then it would be 
deallocated after the callee relinquishes ownership and before the caller can 
retake ownership. Some convention is necessary to keep the object alive across 
the return, whether or not there is a threat of thread interference.


> Therefore there are two practical solutions:
> 
> 1. Retain the object over the window of mis-opportunity. This works fine if 
> the calling site is aware that the callee did it, and this is what happens 
> when both the caller and callee are using ARC conventions. In fact, with ARC, 
> the object is *already* retained in the callee, so this scenario doesn’t 
> *add* a retain, it *removes* a release (that would normally occur at the end 
> of the callee’s scope). And the caller doesn’t have to retain the result, 
> just keep the the release at the end of *its* scope. Win-win-win. Otherwise…
> 
> 2. Retain and autorelease the object prior to returning. This works fine 
> always, because autorelease pools are per-thread, so there’s no change of it 
> being drained during the return process. But it typically adds a net return 
> and release.
> 
> Choosing a strategy is up to the callee, and is based on information about 
> the caller at run-time, not compile or link time. That means it’s not 
> source-language-specific. (The only exception would be if the Swift compiler 
> knew that a function was private and final, so it controlled both ends of the 
> call.)

The Swift compiler can avoid autorelease more often than that. Swift can use a 
simple callee-retain caller-release convention any time it knows that the 
function is not visible to Objective-C. That happens often.


-- 
Greg Parker gpar...@apple.com  Runtime 
Wrangler


___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-14 Thread Greg Parker

> On Jul 14, 2017, at 6:51 AM, Alex Zavatone  wrote:
> 
>> On Jul 14, 2017, at 5:50 AM, Jeremy Hughes  
>> wrote:
>> 
>>> On 12 Jul 2017, at 17:41, Jens Alfke  wrote:
>>> 
 On Jul 12, 2017, at 9:34 AM, Jeremy Hughes  
 wrote:
 
 // Prints "Why is childReference not nil?”
>>> 
>>> There may still be a reference in the autorelease pool. Check 
>>> childReference again ‘later’, i.e. on the next user event or after a 
>>> timer/delayed-perform.
>> 
>> Jens is correct. Here’s a modified version of the playground code that adds 
>> an autorelease pool:
> 
> In the interest of getting more of a clue in regards to these items, is it 
> possible to examine the autorelease pools?

Xcode's memory graph tool can tell you if an object is pointed to by some 
autorelease pool.

You can call _objc_autoreleasePoolPrint() in the debugger to dump the contents 
of the current thread's autorelease pool stack.

You can set environment variable OBJC_PRINT_POOL_HIGHWATER=YES to record stack 
traces when a large autorelease pool is drained.


-- 
Greg Parker gpar...@apple.com  Runtime 
Wrangler


___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-14 Thread Quincey Morris
On Jul 14, 2017, at 03:50 , Jeremy Hughes  wrote:
> 
> I’m still not entirely clear on when autorelease pools are used in Swift.

I think about it this way:

Autorelease is the run-time feature that provides an atomic return.

There is no such thing as an “atomic” return naturally built into in any of the 
run-time environments using ARC (or MRC). That is, if a function result is a 
reference-counted object, there is nothing that naturally prevents the 
reference count from changing during the short window of mis-opportunity from 
when a release occurs just before a callee returns, and the caller gets an 
opportunity to retain the reference. That’s the price of multi-threading.

Therefore there are two practical solutions:

1. Retain the object over the window of mis-opportunity. This works fine if the 
calling site is aware that the callee did it, and this is what happens when 
both the caller and callee are using ARC conventions. In fact, with ARC, the 
object is *already* retained in the callee, so this scenario doesn’t *add* a 
retain, it *removes* a release (that would normally occur at the end of the 
callee’s scope). And the caller doesn’t have to retain the result, just keep 
the the release at the end of *its* scope. Win-win-win. Otherwise…

2. Retain and autorelease the object prior to returning. This works fine 
always, because autorelease pools are per-thread, so there’s no change of it 
being drained during the return process. But it typically adds a net return and 
release.

Choosing a strategy is up to the callee, and is based on information about the 
caller at run-time, not compile or link time. That means it’s not 
source-language-specific. (The only exception would be if the Swift compiler 
knew that a function was private and final, so it controlled both ends of the 
call.)

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-14 Thread John McCall
> On Jul 14, 2017, at 12:22 PM, Charles Srstka  wrote:
>> On Jul 14, 2017, at 10:09 AM, Jeremy Hughes  
>> wrote:
>> 
>>> On 14 Jul 2017, at 14:40, Steve Christensen >> > wrote:
>>> 
>>> On Jul 14, 2017, at 3:50 AM, Jeremy Hughes >> > wrote:
 
 I’m still not entirely clear on when autorelease pools are used in Swift. 
 There is a WWDC video which says that they’re used in code that interfaces 
 with Objective-C, but Greg Parker’s comments in this thread indicate that 
 autorelease is also used behind the scenes in native Swift code - except 
 that in many cases the compiler is able to optimise it out of existence. 
 Apple’s Swift book doesn’t mention autorelease.
>>> 
>>> I think the hazard here is that you are trying to build a mental model of 
>>> when to expect autorelease pools (or autorelease behavior in general) and 
>>> when not to. Worse, that you might design your code to fit those 
>>> expectations.
>> 
>> Apple’s documentation states that there are times that you do want to 
>> consider the memory effects of autorelease pools (and suggests adding your 
>> own pools to prevent large accumulations of dead objects during loops) - so 
>> knowing when they are used isn’t irrelevant.
>> 
>> Also, ARC is described as “deterministic” - which I’m possibly 
>> misinterpreting as meaning "behaves in a predictable way".
>> 
>> Jeremy
> 
> I’d interpret it as “behaves in a consistent way.” Predictable is subjective, 
> especially when autorelease pools are involved.

The word I would use is "reproducible".  As humans, we say something is 
"predictable" when it's easy to say exactly what it's going to do, and like any 
complex program, ARC doesn't generally live up to that — even I wouldn't claim 
that level of understanding of, say, the optimizer.  But if you have a problem 
with ARC, you can usually reproduce it exactly: its implementation model 
doesn't naturally create new inconsistencies where a program behaves 
differently on different runs.

(There are some minor exceptions, of course.  But the major sources of 
inconsistencies between runs are just classic concurrency races that would 
exist in your program without ARC.  ARC may not introduce those, but it also 
doesn't really eliminate them.)

Anyway, here's how I recommend approaching these questions of how you should 
think about ARC.

ARC provides an abstract language model.  Most things in computers do, from 
user-level libraries down to the operating system and even ultimately the 
processor.  What this means is that there are rules to the abstraction that you 
are expected to live by, and those rules are defined not in terms of how some 
specific implementation happens to work but in terms of the higher-level 
abstractions presented to you as a user of the interface.  For example, you 
should not rely on the exact numeric value of POSIX file descriptors, or the 
ordering relationship between two pointers sequentially returned by malloc(), 
or the zero-initialization of the stack at process launch, or the limitations 
of load speculation in current CPU microarchitectures; you should follow the 
rules laid out in the language, library, or processor documentation.

ARC does not make promises about reference counts or when exactly an object 
will be deallocated.  Instead, it makes promises about when an object won't be 
deallocated, and those promises are mostly tied to whether the object is 
currently held by a strong reference.  If you're looking at your program and 
trying to decide if it's correct, those rules are the only thing you should be 
considering.  In this light, it is pretty much never important to be asking 
questions about whether an object is an autorelease pool.  If ARC is keeping an 
object alive by putting it in an autorelease pool, that's pretty much its 
business, as far as correctness is concerned.  *You* need to be thinking about 
whether you have a strong reference to it.

None of that is to say that it's wrong to try to understand the details behind 
abstractions.  Especially with ARC, those details can matter a lot when you're 
tracking down a bug.  And it also matters a lot for performance; for example, 
there are times when ARC does autorelease something to keep it alive, and if 
that autorelease is burning you, you need to figure out why it's happening 
before you can figure out how to avoid it.  And of course it's also just 
interesting.  All I'm saying is that, once you've figured out your problem, you 
have to go back to the abstraction to figure out how to fix it.

John.
___

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 

Re: Who owns a child view controller?

2017-07-14 Thread Quincey Morris
On Jul 14, 2017, at 03:32 , Jeremy Hughes  wrote:
> 
>  one might argue that safe unowned objects could be replaced by 
> unowned(unsafe) objects in release code

It’s highly desirable not to do that, because it’s the bugs that show up in 
release code that are the hardest to find. In fact, Swift has a “stronger” 
level of optimizations called “unsafe”, where the compiler just omits many of 
the safety checks that you normally get even in release code. Whether this 
turns of unowned reference counts is unknown to me.

It’s important (for compiler writers) to reason correctly in this area. Your 
source code might have a couple of variables holding references to a particular 
object, and one of those variables could by unowned. (There has to be at least 
one owning reference as well, otherwise the object wouldn’t exist.) But primary 
retain counts are incremented/decremented basically every time the reference is 
*used*, which can be thousands or millions of times. Secondary retain counts 
are incremented/decremented basically once per variable.

So, if the reference to a particular object is only every used once per 
variable, secondary reference counting doubles to overhead, but only on 
something whose CPU cost is vanishingly small. If the object reference is used 
a lot, the contribution of the secondary retain count to overhead is 
vanishingly small. There’s nothing to complain about here.

The only scenario I can think of where it might matter is when you’re creating 
and destroying variables (as opposed to objects) a lot, such as having an 
“unowned” local variable in the innermost scope of a tight loop. If you do that 
to avoid the overhead of ARC inside the loop, you’re probably not achieving 
your intention. But this is a very specialized scenario.

> I don’t think an unowned variable can be any kind of optional

Yes, it was just wishful thinking on my part. I recently ran into a scenario (a 
“parent” pointer from a child back to its parent in a tree structure), where a 
subtree might temporarily and validly have no parent. If the tree can be large 
(hundreds of thousands of objects), making the “parent” pointer be “weak” 
starts to become unpalatable, due the (presumed) overhead of a big side-table. 
OTOH, the lifetime of a non-nil “parent” pointer is guaranteed to be less than 
the lifetime of a child (because if it has a parent, its parent is retaining 
it, by definition), so it seems like a good candidate for “unowned”.

> I was going to say I think the implicitly unwrapped optional in the Swift 
> book example is a weak value

No, you can create reference cycles with IUOs as easily as with regular 
variables. :)

Again, though, I recommend caution in terminology. I know what you mean here, 
and I think *you* know what you mean here, but there’s no such thing as a “weak 
value”. “Weak” is a property of the container, not the contents.
___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-14 Thread Steve Christensen
On Jul 14, 2017, at 8:09 AM, Jeremy Hughes  wrote:
> 
>> On 14 Jul 2017, at 14:40, Steve Christensen  wrote:
>> 
>> On Jul 14, 2017, at 3:50 AM, Jeremy Hughes  
>> wrote:
>>> 
>>> I’m still not entirely clear on when autorelease pools are used in Swift. 
>>> There is a WWDC video which says that they’re used in code that interfaces 
>>> with Objective-C, but Greg Parker’s comments in this thread indicate that 
>>> autorelease is also used behind the scenes in native Swift code - except 
>>> that in many cases the compiler is able to optimise it out of existence. 
>>> Apple’s Swift book doesn’t mention autorelease.
>> 
>> I think the hazard here is that you are trying to build a mental model of 
>> when to expect autorelease pools (or autorelease behavior in general) and 
>> when not to. Worse, that you might design your code to fit those 
>> expectations.
> 
> Apple’s documentation states that there are times that you do want to 
> consider the memory effects of autorelease pools (and suggests adding your 
> own pools to prevent large accumulations of dead objects during loops) - so 
> knowing when they are used isn’t irrelevant.

What I was getting at is that whether or not an object created by something 
other than your code is in an autorelease pool should be of no concern to you 
(at least with ARC). If your code assigns it to a strong variable, adds it to 
an array, etc., then its retain count will be incremented because your code is 
now becoming a [co-]owner of the object. Whether or not the retain count will 
be decremented someplace else due to an enclosing autorelease pool or some 
other mechanism will not affect that behavior.

If you explicitly create an autorelease pool, such as for reasons that you've 
mentioned above, then you need to be aware that something you created in the 
pool's scope, and want to continue existing beyond the pool's scope, could 
magically disappear when the pool is drained if you're not managing it 
correctly.

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-14 Thread Charles Srstka
> On Jul 14, 2017, at 10:09 AM, Jeremy Hughes  
> wrote:
> 
>> On 14 Jul 2017, at 14:40, Steve Christensen > > wrote:
>> 
>> On Jul 14, 2017, at 3:50 AM, Jeremy Hughes > > wrote:
>>> 
>>> I’m still not entirely clear on when autorelease pools are used in Swift. 
>>> There is a WWDC video which says that they’re used in code that interfaces 
>>> with Objective-C, but Greg Parker’s comments in this thread indicate that 
>>> autorelease is also used behind the scenes in native Swift code - except 
>>> that in many cases the compiler is able to optimise it out of existence. 
>>> Apple’s Swift book doesn’t mention autorelease.
>> 
>> I think the hazard here is that you are trying to build a mental model of 
>> when to expect autorelease pools (or autorelease behavior in general) and 
>> when not to. Worse, that you might design your code to fit those 
>> expectations.
> 
> Apple’s documentation states that there are times that you do want to 
> consider the memory effects of autorelease pools (and suggests adding your 
> own pools to prevent large accumulations of dead objects during loops) - so 
> knowing when they are used isn’t irrelevant.
> 
> Also, ARC is described as “deterministic” - which I’m possibly 
> misinterpreting as meaning "behaves in a predictable way".
> 
> Jeremy

I’d interpret it as “behaves in a consistent way.” Predictable is subjective, 
especially when autorelease pools are involved.

Charles

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-14 Thread Jeremy Hughes
> On 14 Jul 2017, at 14:40, Steve Christensen  wrote:
> 
> On Jul 14, 2017, at 3:50 AM, Jeremy Hughes  
> wrote:
>> 
>> I’m still not entirely clear on when autorelease pools are used in Swift. 
>> There is a WWDC video which says that they’re used in code that interfaces 
>> with Objective-C, but Greg Parker’s comments in this thread indicate that 
>> autorelease is also used behind the scenes in native Swift code - except 
>> that in many cases the compiler is able to optimise it out of existence. 
>> Apple’s Swift book doesn’t mention autorelease.
> 
> I think the hazard here is that you are trying to build a mental model of 
> when to expect autorelease pools (or autorelease behavior in general) and 
> when not to. Worse, that you might design your code to fit those expectations.

Apple’s documentation states that there are times that you do want to consider 
the memory effects of autorelease pools (and suggests adding your own pools to 
prevent large accumulations of dead objects during loops) - so knowing when 
they are used isn’t irrelevant.

Also, ARC is described as “deterministic” - which I’m possibly misinterpreting 
as meaning "behaves in a predictable way".

Jeremy

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-14 Thread Charles Srstka
> On Jul 14, 2017, at 8:51 AM, Alex Zavatone  wrote:
> 
> 
>> On Jul 14, 2017, at 5:50 AM, Jeremy Hughes  
>> wrote:
>> 
>>> On 12 Jul 2017, at 17:41, Jens Alfke  wrote:
>>> 
 On Jul 12, 2017, at 9:34 AM, Jeremy Hughes  
 wrote:
 
 // Prints "Why is childReference not nil?”
>>> 
>>> There may still be a reference in the autorelease pool. Check 
>>> childReference again ‘later’, i.e. on the next user event or after a 
>>> timer/delayed-perform.
>> 
>> Jens is correct. Here’s a modified version of the playground code that adds 
>> an autorelease pool:
> 
> In the interest of getting more of a clue in regards to these items, is it 
> possible to examine the autorelease pools?
> 
> Alex Zavatone

No, autorelease pools have always been maddeningly opaque. You can examine a 
particular object in Instruments though, to see when it’s been autoreleased.

Charles

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-14 Thread Alex Zavatone

> On Jul 14, 2017, at 5:50 AM, Jeremy Hughes  
> wrote:
> 
>> On 12 Jul 2017, at 17:41, Jens Alfke  wrote:
>> 
>>> On Jul 12, 2017, at 9:34 AM, Jeremy Hughes  
>>> wrote:
>>> 
>>> // Prints "Why is childReference not nil?”
>> 
>> There may still be a reference in the autorelease pool. Check childReference 
>> again ‘later’, i.e. on the next user event or after a timer/delayed-perform.
> 
> Jens is correct. Here’s a modified version of the playground code that adds 
> an autorelease pool:

In the interest of getting more of a clue in regards to these items, is it 
possible to examine the autorelease pools?

Alex Zavatone
___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-14 Thread Steve Christensen
On Jul 14, 2017, at 3:50 AM, Jeremy Hughes  wrote:
> 
> I’m still not entirely clear on when autorelease pools are used in Swift. 
> There is a WWDC video which says that they’re used in code that interfaces 
> with Objective-C, but Greg Parker’s comments in this thread indicate that 
> autorelease is also used behind the scenes in native Swift code - except that 
> in many cases the compiler is able to optimise it out of existence. Apple’s 
> Swift book doesn’t mention autorelease.

I think the hazard here is that you are trying to build a mental model of when 
to expect autorelease pools (or autorelease behavior in general) and when not 
to. Worse, that you might design your code to fit those expectations.

I think it's a lot safer to understand how strong/weak/unowned work and go from 
there. You do the appropriate thing to hang onto an object while you're using 
it and then do the appropriate thing when you're done with it (which might be 
as simple as setting a variable to nil). Once you're done with the object, it's 
somebody else's task to make sure that the right things happen at the right 
time (that's their right time, not yours).

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-14 Thread Alastair Houghton
On 14 Jul 2017, at 12:03, Jeremy Hughes  wrote:
> 
>> On 13 Jul 2017, at 20:29, Alex Zavatone  wrote:
>> 
>> One thing that I had to learn was to break my expectations of when a view 
>> controller (one that is tied to a navigationController) is deallocated.
> 
> I’m not sure that view controllers are special. My understanding is that 
> objects that are instantiated from a nib are not (usually or ever?) 
> deallocated

Strictly, it depends which method you used to load the nib file.  The older 
(and IIRC deprecated?) methods used to load the top-level objects in a nib with 
a non-zero retain count, which meant that they’d survive unless you explicitly 
-release them (retain cycles notwithstanding), in spite of the fact that you 
usually only have a reference to them if you’ve wired up an IBOutlet.  The 
newer methods don’t do that - instead, they pass out an NSArray containing 
references to all of the top-level objects; any objects you don’t hold on to 
directly (either by retaining the array or by retaining specific top level 
objects) will be destroyed, either by ARC or via the surrounding autorelease 
pool.

Both methods, strictly speaking, follow “normal” memory rules... which makes 
more sense mainly depends on your view of what a nib file is.  If you regard 
the objects in the nib file as actual instances, then it makes sense that 
they’d have a non-zero retain count - after all, they’re in the nib file, 
right?  If, on the other hand, you think of the nib loading system as 
*creating* objects based on a nib file, the newer way makes more sense. The 
newer approach also, I suspect, plays nicer with ARC and makes it less likely 
you’ll accidentally leak objects from nibs you load.

> In addition to autorelease pools there could be other behind-the-scenes 
> mechanisms (caches etc.) that have retain counts.

Indeed, and you might also find that some objects are singletons behind the 
scenes, so could end up with quite unexpected retain counts.  For instance, 
there’s little point in having thousands of empty NSString instances, or 
thousands of NSNumber instances containing 0 or 1.  (I haven’t checked to what 
extent this happens, but I imagine it does.)

Kind regards,

Alastair.

--
http://alastairs-place.net

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-14 Thread Jeremy Hughes
> On 13 Jul 2017, at 20:29, Alex Zavatone  wrote:
> 
> One thing that I had to learn was to break my expectations of when a view 
> controller (one that is tied to a navigationController) is deallocated.


I’m not sure that view controllers are special. My understanding is that 
objects that are instantiated from a nib are not (usually or ever?) deallocated 
- there is always a top-level object that holds a retain count - but objects 
that are created programmatically follow normal memory rules - they are 
deallocated when you (and any autorelease pools) no longer hold a retain count.

I could be wrong.

In addition to autorelease pools there could be other behind-the-scenes 
mechanisms (caches etc.) that have retain counts.

Jeremy

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-14 Thread Jeremy Hughes
> On 12 Jul 2017, at 17:41, Jens Alfke  wrote:
> 
>> On Jul 12, 2017, at 9:34 AM, Jeremy Hughes  
>> wrote:
>> 
>> // Prints "Why is childReference not nil?”
> 
> There may still be a reference in the autorelease pool. Check childReference 
> again ‘later’, i.e. on the next user event or after a timer/delayed-perform.

Jens is correct. Here’s a modified version of the playground code that adds an 
autorelease pool:

import Cocoa

let parent = NSViewController()
var child: NSViewController? = NSViewController()
weak var childReference: NSViewController? = child

autoreleasepool
{
parent.addChildViewController(child!)

child = nil

parent.childViewControllers = []
}

if childReference == nil
{
print("childReference is nil")
}
else
{
print("Why is childReference not nil?")
}

// Prints "childReference is nil"

I’m still not entirely clear on when autorelease pools are used in Swift. There 
is a WWDC video which says that they’re used in code that interfaces with 
Objective-C, but Greg Parker’s comments in this thread indicate that 
autorelease is also used behind the scenes in native Swift code - except that 
in many cases the compiler is able to optimise it out of existence. Apple’s 
Swift book doesn’t mention autorelease.

For practical purposes, it seems that you need to be aware of autorelease pools 
when using Cocoa (or Objective-C) objects, but you don’t normally need to be 
aware of them when using native Swift objects.

Jeremy

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-14 Thread Jeremy Hughes
> On 13 Jul 2017, at 19:43, Quincey Morris 
>  wrote:
> 
> Here’s how I understand the situation in Swift. As usual, I may have some 
> things a bit wrong, but I think this is right. There are four kinds of 
> reference variable (or stored property) in Swift:
> 
> 1. Strong.
> 
> 2. Weak.
> 
> 3. Unowned(safe), usually abbreviated to just “unowned”.
> 
> 4. Unowned(unsafe).
> 
> Note that these are attributes of the variable (i.e. storage location), not 
> the reference (i.e. pointer). It’s easy to forget that and talk about “strong 
> references” for example, but technically there’s no such thing.

Thanks Quincey - this is a really helpful discussion!

> “Unowned” means that the reference is non-optional and can persist after the 
> referenced object is deallocated. This avoids the performance penalty of 
> “weak”, but can’t provide a validity guarantee for the pointer — it’s up to 
> you to keep the object alive for as long as you use the unowned variable’s 
> reference. The clever part, which is specific to Swift, is that objects 
> secretly have *another* retain count, which is the number of *unowned* 
> variable references to the object. An object is not actually deallocated 
> until *both* retain counts go to zero — at which point there are obviously no 
> references to it any more. If you try to use an unowned variable reference 
> while the *main* reference count is zero and the *unowned* reference count is 
> non-zero, you are trying to use a zombie object and your app will immediately 
> crash.
> 
> Think about this. In effect, all Swift apps have zombie checking on all the 
> time. It’s impossible to use a reference to a non-alive object, and it’s 
> impossible for a stale pointer to refer to an instance of a different class 
> (which can happen in Obj-C if memory is re-allocated for another object while 
> you still hold a pointer to it.) It’s a simple but brilliant idea. It’s 
> pretty cheap, and it crashes as early as possible, which makes debugging 
> easier. What Dave meant, in the things you quoted, is that there’s an 
> overhead to this.  Aside from questions of optimization, the overhead is 
> similar to “strong” retain counting.

The secret retain count of unowned objects definitely helps to explain Dave’s 
comment, which was otherwise confusing. Without knowing this, it’s easy to get 
tied up in knots, as I was doing - if unowned objects have a retain count, how 
are they different from strong objects, and if they don’t have a retain count, 
how are they different from unowned(unsafe) objects? Your answer, which I 
haven’t seen elsewhere but was starting to suspect, is that they have a second 
retain count.

> “Unowned(unsafe)” means the same thing as “unretained unsafe” in Obj-C. It’s 
> just a pointer, and you’re responsible for knowing it’s safe to use at any 
> given time. Obviously, you’d like never to see one of these in Swift code.

Except for performance reasons, as you later say. Thinking about this, one 
might argue that safe unowned objects could be replaced by unowned(unsafe) 
objects in release code - in the same way that asserts are compiled out (and 
zombies are turned off) in release code. On the other hand, it’s easier for 
users to send bug reports if their crashes are repeatable. [I haven’t 
investigated, but maybe safe unowned objects are actually replaced by unsafe 
unowned objects with some optimisation settings?]

> The usage rules for these things are pretty straightforward to state, even 
> though it might be harder in particular cases to be sure what to use.
> 
> For owning variables, use strong. By default, use weak the rest of the time. 
> If you can reason that a non-owning variable is going to contain a valid 
> reference once initially set (like a “parent” reference in a child object to 
> which the parent has an owning reference in its “children” array, or like an 
> IBOutlet reference, usually), you can avoid the overhead of “weak” and use 
> “unowned” instead. (IIRC, you *must* declare a weak variable as optional, you 
> *must not* declare an unowned variable as optional, but you can declare 
> *either* as implicitly unwrapped optional.)

I don’t think an unowned variable can be any kind of optional, implicitly 
unwrapped or not. You might have been thinking of a discussion in the Swift 
book which deals with the question of how to have circular references (class A 
refers to B and class B refers to A) where both properties should have a value 
and neither should be nil. You can’t use unowned for both because init rules 
will prevent you from passing self to the other initialiser before you have 
finished initialising the first object. The book suggests that you could around 
this by using an implicitly unwrapped optional in one of the objects (this 
seems a bit kludgy to me). [See “Unowned References and Implicitly Unwrapped 
Optional Properties” in the ARC chapter.]

I was going to say I think the implicitly 

Re: Who owns a child view controller?

2017-07-14 Thread Saagar Jha
I don't think view controllers are actually unloaded under memory pressure
anymore. I think I remember reading about that somewhere, but I'll have to
go hunt for it again.
On Thu, Jul 13, 2017 at 12:29 Alex Zavatone  wrote:

> One thing that I had to learn was to break my expectations of when a view
> controller (one that is tied to a navigationController) is deallocated.
>
> My expectations initially were “oh, we’re closing it and going to another
> screen, it will just be deallocated.”
>
> Weee, no.  It’s part of a stack of view controllers if it’s in a
> navigation controller and the entire stack is what is needed for the user
> to be able to travel back and forth within the list of controllers that are
> “under” that nav controller.
>
> I expect that if the app comes under memory pressure, the instantiated VCs
> will be faulted to disk and if even more pressure, they may be deallocated.
>
> But I’m not really sure about that.
>
> The one thing that I am aware of is that, “just because the user moves on
> to another view controller, that doesn’t mean that the one they left is
> deallocated.  I leave that to the OS to figure out.  If I have a set of
> view controllers that act as a module, I open a new storyboard, with a new
> nav controller, so that I when complete, I can close the whole thing by
> dismissing it and since there are no more references left, all the memory
> for the whole section is just returned as everything deallocates.  This
> approach has worked worked pretty well for me for about 4 years now in
> iOS.  It’s not applicable everywhere though.
>
> Cheers,
> Alex Zavatone
>
> > On Jul 13, 2017, at 4:57 AM, Jeremy Hughes 
> wrote:
> >
> >> On 13 Jul 2017, at 01:32, Jens Alfke  wrote:
> >>
> >>> On Jul 12, 2017, at 2:57 PM, Jeremy Hughes <
> moon.rab...@virginmedia.com> wrote:
> >>>
> >>> I’m trying to understand memory management so I can avoid retain
> cycles and other issues.
> >>
> >> That’s fine. But using a weak reference to try to detect when an object
> gets dealloced is fraught with peril, viz. this entire thread :)
> >
> > That was some test code I wrote to investigate a situation I noticed
> while debugging. The actual issue is whether an object (view controller) is
> deallocated rather than when it is deallocated.
> >
> >> On 13 Jul 2017, at 01:32, Jens Alfke  wrote:
> >>
> >> If you want to find out if your code is leaking by creating reference
> cycles, just run it and ask either Instruments or Xcode to find leaks.
> >
> > I was hoping to avoid creating cycles in the first place...
> >
> >> On 13 Jul 2017, at 00:15, Quincey Morris <
> quinceymor...@rivergatesoftware.com> wrote:
> >>
> >> I may be overlooking something important, but I see basically three
> tasks you need to handle to avoid memory management bugs:
> >>
> >> 1. Strong references.
> >>
> >> 2. Weak references.
> >>
> >> 3. Unowned/unsafe references.
> >
> > I’ve abbreviated this summary - but the things that I find confusing are:
> >
> > 1. When to use unowned rather than weak. I’ve read Apple’s Swift book
> and other discussions, and one explanation I found is that unowned is a bit
> like forced unwrapping - you can (or should) use it when you’re sure that
> the reference will always be valid, and it saves you from having to use an
> optional. According to Greg Parker’s email there is also unsafe unretained
> which is different from unowned. I think that unsafe unretained is the same
> as unowned(unsafe) in Swift, but I could be wrong.
> >
> > There is a thread on Stack Overflow where people are confused about the
> difference between unowned and unowned(unsafe).
> >
> >
> https://stackoverflow.com/questions/26553924/what-is-the-difference-in-swift-between-unownedsafe-and-unownedunsafe
> >
> > According to a comment from Dave Abrahams (who I think works at Apple):
> >
> > "unowned and unowned(safe) do incur reference counting cost—that is the
> cost of safety, and why even make unowned(unsafe) available otherwise?—and
> it’s currently worse than regular strong reference counting cost because
> ARC isn’t optimizing for it. Neither throws an exception; they trap when
> misused, permanently stopping the program”
> >
> > But if unowned is a synonym for unowned(safe), I’m not sure what
> “Neither” means in the last sentence - is he talking about safe and unsafe
> unowned, or just unsafe unowned?
> >
> > Apple’s Swift book says:
> >
> > "The examples above show how to use safe unowned references. Swift also
> provides unsafe unowned references for cases where you need to disable
> runtime safety checks—for example, for performance reasons. As with all
> unsafe operations, you take on the responsiblity for checking that code for
> safety.
> >
> > "You indicate an unsafe unowned reference by writing unowned(unsafe). If
> you try to access an unsafe unowned reference after the instance that it
> refers to is deallocated, your 

Re: Who owns a child view controller?

2017-07-13 Thread Alex Zavatone
One thing that I had to learn was to break my expectations of when a view 
controller (one that is tied to a navigationController) is deallocated.

My expectations initially were “oh, we’re closing it and going to another 
screen, it will just be deallocated.”  

Weee, no.  It’s part of a stack of view controllers if it’s in a navigation 
controller and the entire stack is what is needed for the user to be able to 
travel back and forth within the list of controllers that are “under” that nav 
controller.

I expect that if the app comes under memory pressure, the instantiated VCs will 
be faulted to disk and if even more pressure, they may be deallocated.  

But I’m not really sure about that.  

The one thing that I am aware of is that, “just because the user moves on to 
another view controller, that doesn’t mean that the one they left is 
deallocated.  I leave that to the OS to figure out.  If I have a set of view 
controllers that act as a module, I open a new storyboard, with a new nav 
controller, so that I when complete, I can close the whole thing by dismissing 
it and since there are no more references left, all the memory for the whole 
section is just returned as everything deallocates.  This approach has worked 
worked pretty well for me for about 4 years now in iOS.  It’s not applicable 
everywhere though.

Cheers,
Alex Zavatone

> On Jul 13, 2017, at 4:57 AM, Jeremy Hughes  
> wrote:
> 
>> On 13 Jul 2017, at 01:32, Jens Alfke  wrote:
>> 
>>> On Jul 12, 2017, at 2:57 PM, Jeremy Hughes  
>>> wrote:
>>> 
>>> I’m trying to understand memory management so I can avoid retain cycles and 
>>> other issues.
>> 
>> That’s fine. But using a weak reference to try to detect when an object gets 
>> dealloced is fraught with peril, viz. this entire thread :)
> 
> That was some test code I wrote to investigate a situation I noticed while 
> debugging. The actual issue is whether an object (view controller) is 
> deallocated rather than when it is deallocated.
> 
>> On 13 Jul 2017, at 01:32, Jens Alfke  wrote:
>> 
>> If you want to find out if your code is leaking by creating reference 
>> cycles, just run it and ask either Instruments or Xcode to find leaks.
> 
> I was hoping to avoid creating cycles in the first place...
> 
>> On 13 Jul 2017, at 00:15, Quincey Morris 
>>  wrote:
>> 
>> I may be overlooking something important, but I see basically three tasks 
>> you need to handle to avoid memory management bugs:
>> 
>> 1. Strong references.
>> 
>> 2. Weak references.
>> 
>> 3. Unowned/unsafe references.
> 
> I’ve abbreviated this summary - but the things that I find confusing are:
> 
> 1. When to use unowned rather than weak. I’ve read Apple’s Swift book and 
> other discussions, and one explanation I found is that unowned is a bit like 
> forced unwrapping - you can (or should) use it when you’re sure that the 
> reference will always be valid, and it saves you from having to use an 
> optional. According to Greg Parker’s email there is also unsafe unretained 
> which is different from unowned. I think that unsafe unretained is the same 
> as unowned(unsafe) in Swift, but I could be wrong.
> 
> There is a thread on Stack Overflow where people are confused about the 
> difference between unowned and unowned(unsafe).
> 
> https://stackoverflow.com/questions/26553924/what-is-the-difference-in-swift-between-unownedsafe-and-unownedunsafe
> 
> According to a comment from Dave Abrahams (who I think works at Apple):
> 
> "unowned and unowned(safe) do incur reference counting cost—that is the cost 
> of safety, and why even make unowned(unsafe) available otherwise?—and it’s 
> currently worse than regular strong reference counting cost because ARC isn’t 
> optimizing for it. Neither throws an exception; they trap when misused, 
> permanently stopping the program”
> 
> But if unowned is a synonym for unowned(safe), I’m not sure what “Neither” 
> means in the last sentence - is he talking about safe and unsafe unowned, or 
> just unsafe unowned?
> 
> Apple’s Swift book says:
> 
> "The examples above show how to use safe unowned references. Swift also 
> provides unsafe unowned references for cases where you need to disable 
> runtime safety checks—for example, for performance reasons. As with all 
> unsafe operations, you take on the responsiblity for checking that code for 
> safety.
> 
> "You indicate an unsafe unowned reference by writing unowned(unsafe). If you 
> try to access an unsafe unowned reference after the instance that it refers 
> to is deallocated, your program will try to access the memory location where 
> the instance used to be, which is an unsafe operation.”
> 
> At this point I’m pretty confused about the difference between strong and 
> safe unowned. I understand that strong retains its reference, but it seems to 
> me that Dave Abrahams and Apple’s Swift 

Re: Who owns a child view controller?

2017-07-13 Thread Quincey Morris
On Jul 13, 2017, at 02:57 , Jeremy Hughes  wrote:
> 
> When to use unowned rather than weak

Here’s how I understand the situation in Swift. As usual, I may have some 
things a bit wrong, but I think this is right. There are four kinds of 
reference variable (or stored property) in Swift:

1. Strong.

2. Weak.

3. Unowned(safe), usually abbreviated to just “unowned”.

4. Unowned(unsafe).

Note that these are attributes of the variable (i.e. storage location), not the 
reference (i.e. pointer). It’s easy to forget that and talk about “strong 
references” for example, but technically there’s no such thing.


“Strong” means that the variable retains its reference. No surprises here.

All of the other cases do *not* retain their reference. That is, they do not 
increment the object’s retain count. But there are other things going on that 
account for the differences between them.

“Weak” means the reference is optional, can be nil, and is automatically set to 
nil if the referenced object is deallocated. This is safe, because you can’t 
end up trying to follow an invalid pointer: Swift guarantees that you will see 
a valid pointer or nil. The downside of “weak” is that a side-table of non-nil 
weak variable addresses is maintained somewhere, so that weak variables can be 
nil'ed on deallocation of the referenced object. There is some performance 
overhead to this, especially as there must obviously be some kind of locking 
mechanism to provide thread safety.

“Unowned” means that the reference is non-optional and can persist after the 
referenced object is deallocated. This avoids the performance penalty of 
“weak”, but can’t provide a validity guarantee for the pointer — it’s up to you 
to keep the object alive for as long as you use the unowned variable’s 
reference. The clever part, which is specific to Swift, is that objects 
secretly have *another* retain count, which is the number of *unowned* variable 
references to the object. An object is not actually deallocated until *both* 
retain counts go to zero — at which point there are obviously no references to 
it any more. If you try to use an unowned variable reference while the *main* 
reference count is zero and the *unowned* reference count is non-zero, you are 
trying to use a zombie object and your app will immediately crash.

Think about this. In effect, all Swift apps have zombie checking on all the 
time. It’s impossible to use a reference to a non-alive object, and it’s 
impossible for a stale pointer to refer to an instance of a different class 
(which can happen in Obj-C if memory is re-allocated for another object while 
you still hold a pointer to it.) It’s a simple but brilliant idea. It’s pretty 
cheap, and it crashes as early as possible, which makes debugging easier. What 
Dave meant, in the things you quoted, is that there’s an overhead to this.  
Aside from questions of optimization, the overhead is similar to “strong” 
retain counting.

“Unowned(unsafe)” means the same thing as “unretained unsafe” in Obj-C. It’s 
just a pointer, and you’re responsible for knowing it’s safe to use at any 
given time. Obviously, you’d like never to see one of these in Swift code.


The usage rules for these things are pretty straightforward to state, even 
though it might be harder in particular cases to be sure what to use.

For owning variables, use strong. By default, use weak the rest of the time. If 
you can reason that a non-owning variable is going to contain a valid reference 
once initially set (like a “parent” reference in a child object to which the 
parent has an owning reference in its “children” array, or like an IBOutlet 
reference, usually), you can avoid the overhead of “weak” and use “unowned” 
instead. (IIRC, you *must* declare a weak variable as optional, you *must not* 
declare an unowned variable as optional, but you can declare *either* as 
implicitly unwrapped optional.)

In general, don’t use “unowned(unsafe)”. You should only see it in legacy APIs 
in the SDKs, where for historical reasons it can’t be declared more 
definitively as something safer. You might occasionally use it in your own code 
if the secondary reference counting of “unowned(safe)” happens to be a 
performance problem.

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-13 Thread Charles Srstka
> On Jul 12, 2017, at 6:30 PM, Quincey Morris 
>  wrote:
> 
> On Jul 12, 2017, at 16:19 , Greg Parker  > wrote:
>> 
>> "Unowned" means something else in Swift.
> 
> I suppose. I guess I’ve internalized “unowned” to mean “unretained but 
> crashes tidily” in Swift, but “unretained and crashes as messily as possible” 
> in Obj-C. :) Plus, Swift has “unowned(unsafe)” which means the same thing as 
> “unretained unsafe” in Obj-C.
> 
> (And, yes, I know that Swift “unowned” isn’t precisely unretained. Whoever 
> thought of this trick should get a round of applause.)
> 
> But you drove to me to look at the NSWindow documentation, and it appears 
> that the “delegate” property is (now) weak, not unsafe unretained. I’m not 
> sure when this changed.


It’s in the 10.13 release notes, so whether it’s actually changed yet is up to 
interpretation. ;-)

Charles

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-13 Thread Jeremy Hughes
> On 13 Jul 2017, at 11:26, Jeremy Hughes  wrote:
> 
> So perhaps the difference between safe and unsafe unowned is that safe 
> unowned generates a runtime error (but doesn’t crash) while unsafe unowned 
> crashes? Or perhaps they both crash, but unowned(unsafe) gives a more helpful 
> error message?

Here’s some playground code:

import Foundation

class Element
{
var name = "name"
}

var element1: Element? = Element()

unowned var element2 = element1!

element1 = nil

var element3 = element2

When Xcode (8.2.1) doesn’t crash (which seems to happen quite frequently with 
playgrounds) I get the following error:

Execution was interrupted, reason: EXC_BREAKPOINT (code=EXC_I386_BPT, 
subcode=0x0).

If I change unowned to unowned(unsafe) I sometimes get a more informative error:

Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x20).

EXC_BAD_ACCESS is more informative than EXC_BREAKPOINT because it’s obviously a 
memory error.

But sometimes I don’t get an error.

By inference, unowned is safer than unowned(unsafe) because it crashes 
predictably. But this is tangential to other memory questions because I’m not 
planning to use unowned(unsafe) in my own code.

Jeremy

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-13 Thread Jeremy Hughes
> On 13 Jul 2017, at 10:57, Jeremy Hughes  wrote:
> 
> Apple’s Swift book says:
> 
> "The examples above show how to use safe unowned references. Swift also 
> provides unsafe unowned references for cases where you need to disable 
> runtime safety checks—for example, for performance reasons. As with all 
> unsafe operations, you take on the responsiblity for checking that code for 
> safety.
> 
> "You indicate an unsafe unowned reference by writing unowned(unsafe). If you 
> try to access an unsafe unowned reference after the instance that it refers 
> to is deallocated, your program will try to access the memory location where 
> the instance used to be, which is an unsafe operation.”
> 
> At this point I’m pretty confused about the difference between strong and 
> safe unowned. I understand that strong retains its reference, but it seems to 
> me that Dave Abrahams and Apple’s Swift book are saying or implying that 
> (safe) unowned also retains its reference - so the consequence of using 
> (safe) unowned incorrectly is that it will create a retain cycle, whereas 
> using unowned(unsafe) incorrectly will crash. But if unowned(safe) retains 
> its reference, how is it different from strong (apart from whether ARC is 
> currently optimising for it)?

That last paragraph is wrong, since the Swift book also says:

"IMPORTANT
Use an unowned reference only when you are sure that the reference always 
refers to an instance that has not been deallocated.
If you try to access the value of an unowned reference after that instance has 
been deallocated, you’ll get a runtime error.”

So perhaps the difference between safe and unsafe unowned is that safe unowned 
generates a runtime error (but doesn’t crash) while unsafe unowned crashes? Or 
perhaps they both crash, but unowned(unsafe) gives a more helpful error message?

Jeremy

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-13 Thread Jeremy Hughes
> On 13 Jul 2017, at 01:32, Jens Alfke  wrote:
> 
>> On Jul 12, 2017, at 2:57 PM, Jeremy Hughes  
>> wrote:
>> 
>> I’m trying to understand memory management so I can avoid retain cycles and 
>> other issues.
> 
> That’s fine. But using a weak reference to try to detect when an object gets 
> dealloced is fraught with peril, viz. this entire thread :)

That was some test code I wrote to investigate a situation I noticed while 
debugging. The actual issue is whether an object (view controller) is 
deallocated rather than when it is deallocated.

> On 13 Jul 2017, at 01:32, Jens Alfke  wrote:
> 
> If you want to find out if your code is leaking by creating reference cycles, 
> just run it and ask either Instruments or Xcode to find leaks.

I was hoping to avoid creating cycles in the first place...

> On 13 Jul 2017, at 00:15, Quincey Morris 
>  wrote:
> 
> I may be overlooking something important, but I see basically three tasks you 
> need to handle to avoid memory management bugs:
> 
> 1. Strong references.
> 
> 2. Weak references.
> 
> 3. Unowned/unsafe references.

I’ve abbreviated this summary - but the things that I find confusing are:

1. When to use unowned rather than weak. I’ve read Apple’s Swift book and other 
discussions, and one explanation I found is that unowned is a bit like forced 
unwrapping - you can (or should) use it when you’re sure that the reference 
will always be valid, and it saves you from having to use an optional. 
According to Greg Parker’s email there is also unsafe unretained which is 
different from unowned. I think that unsafe unretained is the same as 
unowned(unsafe) in Swift, but I could be wrong.

There is a thread on Stack Overflow where people are confused about the 
difference between unowned and unowned(unsafe).

https://stackoverflow.com/questions/26553924/what-is-the-difference-in-swift-between-unownedsafe-and-unownedunsafe

According to a comment from Dave Abrahams (who I think works at Apple):

"unowned and unowned(safe) do incur reference counting cost—that is the cost of 
safety, and why even make unowned(unsafe) available otherwise?—and it’s 
currently worse than regular strong reference counting cost because ARC isn’t 
optimizing for it. Neither throws an exception; they trap when misused, 
permanently stopping the program”

But if unowned is a synonym for unowned(safe), I’m not sure what “Neither” 
means in the last sentence - is he talking about safe and unsafe unowned, or 
just unsafe unowned?

Apple’s Swift book says:

"The examples above show how to use safe unowned references. Swift also 
provides unsafe unowned references for cases where you need to disable runtime 
safety checks—for example, for performance reasons. As with all unsafe 
operations, you take on the responsiblity for checking that code for safety.

"You indicate an unsafe unowned reference by writing unowned(unsafe). If you 
try to access an unsafe unowned reference after the instance that it refers to 
is deallocated, your program will try to access the memory location where the 
instance used to be, which is an unsafe operation.”

At this point I’m pretty confused about the difference between strong and safe 
unowned. I understand that strong retains its reference, but it seems to me 
that Dave Abrahams and Apple’s Swift book are saying or implying that (safe) 
unowned also retains its reference - so the consequence of using (safe) unowned 
incorrectly is that it will create a retain cycle, whereas using 
unowned(unsafe) incorrectly will crash. But if unowned(safe) retains its 
reference, how is it different from strong (apart from whether ARC is currently 
optimising for it)?

2. When to use weak or unowned in closure capture lists (rather than default to 
strong) is also pretty confusing! Presumably the default strong option is 
correct for some or most closures, but I don’t have a very clear idea of when 
it’s not correct.

3. Whether (and when) it’s necessary to avoid using functions or class 
variables whose name begins with new or copy. I don’t think this is discussed 
in Apple’s Swift book (or I haven’t found where it’s discussed), but I think 
it’s necessary for classes that interface with Objective C in some way (e.g. 
subclasses of Cocoa classes).

My experience of memory management in Objective-C and Swift (after many years 
of experience with C and C++) is that it mostly “just works” (as Apple say in 
the Swift book) - but there are many cases where you need a deeper 
understanding and it’s hard to find clear explanations.

Jeremy




___

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:

Re: Who owns a child view controller?

2017-07-12 Thread Jens Alfke

> On Jul 12, 2017, at 2:03 PM, Greg Parker  wrote:
> 
> The benefit of the autoreleasing convention comes when you can return an 
> unretained value without a retain/autorelease pair, because you "know" that 
> the object will live long enough for the callee to use it. This does in fact 
> avoid lots of retain/release pairs in carefully written code.

Yes, this is what I was referring to. I’d forgotten that ARC won’t do this, 
because it has to guarantee safety. In my pre-ARC code I routinely did this, 
and only ran into problems with it a handful of times, so I felt it was a 
valuable optimization (especially in the early 2000s when CPUs were slower.)

—Jens
___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Jens Alfke

> On Jul 12, 2017, at 2:57 PM, Jeremy Hughes  
> wrote:
> 
> I’m trying to understand memory management so I can avoid retain cycles and 
> other issues.

That’s fine. But using a weak reference to try to detect when an object gets 
dealloced is fraught with peril, viz. this entire thread :)

If you want to find out if your code is leaking by creating reference cycles, 
just run it and ask either Instruments or Xcode to find leaks.

—Jens
___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Quincey Morris
On Jul 12, 2017, at 16:19 , Greg Parker  wrote:
> 
> "Unowned" means something else in Swift.

I suppose. I guess I’ve internalized “unowned” to mean “unretained but crashes 
tidily” in Swift, but “unretained and crashes as messily as possible” in Obj-C. 
:) Plus, Swift has “unowned(unsafe)” which means the same thing as “unretained 
unsafe” in Obj-C.

(And, yes, I know that Swift “unowned” isn’t precisely unretained. Whoever 
thought of this trick should get a round of applause.)

But you drove to me to look at the NSWindow documentation, and it appears that 
the “delegate” property is (now) weak, not unsafe unretained. I’m not sure when 
this changed.

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Greg Parker

> On Jul 12, 2017, at 4:15 PM, Quincey Morris 
>  wrote:
> 
>> On Jul 12, 2017, at 14:57 , Jeremy Hughes  
>> wrote:
>> 
>> I’m trying to understand memory management so I can avoid retain cycles and 
>> other issues.
> 
> There’s nothing wrong with trying to understand. The bet you will (almost 
> always) lose is one involving reasoning about *when* retain counts reach 
> particular values (such as 1 or 0).
> 
> I may be overlooking something important, but I see basically three tasks you 
> need to handle to avoid memory management bugs:
> 
> 1. Strong references.
> 
> In terms of object lifetimes, these are the easiest, because an object A that 
> depends on an object B’s existence and keeps a strong reference to B is doing 
> the right thing. There’s nothing here to worry about, assuming the reference 
> to B is released normally (and *automatically* usually) when A deallocates. 
> What you do have to worry about are reference cycles. You must either use 
> something like Instruments to find any, and either avoid creating them, or 
> ensure that you break them manually at a suitable time.
> 
> 2. Weak references.
> 
> This means zeroing weak references. (All weak references are zeroing since, 
> IIRC, macOS 10.6.8.) Again, there’s nothing to do here, except to ensure that 
> nothing crashes because a reference suddenly changes to nil.
> 
> 3. Unowned/unsafe references.
> 
> These are the killers. Typically, these are delegate references, but it’s 
> hard to keep track of all the possibilities. For example, NSWindow’s 
> “delegate” is still AFAIK unsafe. It’s usually set to the window controller, 
> but I’m not aware of any typical bugs arising from this reference becoming 
> invalid. The most common problem I know of is from table and outline view 
> delegate and data source references. In many cases, it’s wise to nil these 
> out manually when (say) your window closes.

We prefer to use "unretained" or "unsafe unretained" to describe this kind of 
reference. "Unowned" means something else in Swift.


-- 
Greg Parker gpar...@apple.com  Runtime 
Wrangler


___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Quincey Morris
On Jul 12, 2017, at 14:57 , Jeremy Hughes  wrote:
> 
> I’m trying to understand memory management so I can avoid retain cycles and 
> other issues.

There’s nothing wrong with trying to understand. The bet you will (almost 
always) lose is one involving reasoning about *when* retain counts reach 
particular values (such as 1 or 0).

I may be overlooking something important, but I see basically three tasks you 
need to handle to avoid memory management bugs:

1. Strong references.

In terms of object lifetimes, these are the easiest, because an object A that 
depends on an object B’s existence and keeps a strong reference to B is doing 
the right thing. There’s nothing here to worry about, assuming the reference to 
B is released normally (and *automatically* usually) when A deallocates. What 
you do have to worry about are reference cycles. You must either use something 
like Instruments to find any, and either avoid creating them, or ensure that 
you break them manually at a suitable time.

2. Weak references.

This means zeroing weak references. (All weak references are zeroing since, 
IIRC, macOS 10.6.8.) Again, there’s nothing to do here, except to ensure that 
nothing crashes because a reference suddenly changes to nil.

3. Unowned/unsafe references.

These are the killers. Typically, these are delegate references, but it’s hard 
to keep track of all the possibilities. For example, NSWindow’s “delegate” is 
still AFAIK unsafe. It’s usually set to the window controller, but I’m not 
aware of any typical bugs arising from this reference becoming invalid. The 
most common problem I know of is from table and outline view delegate and data 
source references. In many cases, it’s wise to nil these out manually when 
(say) your window closes.

> I have a view hierarchy that is constructed programmatically.
> 
> This involves creating a view controller and a view, and then creating child 
> view controllers and views in a tree hierarchy. Child view controllers are 
> added to parent view controllers - so that (as I understand it) the parent 
> view controller owns the child view controller. Each view controller is given 
> a view, which it presumably owns, and each view is attached to a superview, 
> which also (presumably) owns the child view. So a view is owned by its view 
> controller and by its superview.
> 
> There is also a top-level view controller that comes from a nib.
> 
> If I release the child view controllers of this top-level view controller (by 
> assigning an empty array to childViewControllers), my expectation is that I 
> don’t have to release every view controller and view in the hierarchy because 
> they are effectively owned by the top-level view controller.

What you’re describing here is a hierarchy of strong references (in the “down” 
direction, with possibly weak references pointing “up”), so there’s not much to 
think about or do.

The real problem in this scenario is that the relationships between window and 
view controllers, windows and views of various types (not to mention a document 
instance in many cases) are extremely, messily intertwined, pretty much for 
ancient historical reasons. Trying to understand the *timing* of destruction in 
a window-closing scenario is hard, and if you do figure out what happened, 
you’ll end up thinking, “That’s weird, I wouldn’t have expected it to come out 
like that.”

I don’t know of any magic bullets for this, though someone else might jump in 
with more specific advice. My advice would be, simply choose a pattern for 
putting your apps’ UIs together, and stick to it.


___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Jeremy Hughes
> On 12 Jul 2017, at 23:18, Doug Hill  wrote:
> 
> While this discussion has been good at understanding underlying ARC and 
> manual ref-count issues, my guess as to what's causing these issues is that 
> you shouldn't just assign nil to the childViewControllers array. 

Actually an empty array rather than nil

> You should try calling:
> 
> childVC.removeFromParentViewController()
> 
> for each child view controller.

The documentation for childViewControllers says:

You can add or remove child view controllers by using this property. When you 
do, the addChildViewController(_:) or removeFromParentViewController() method 
gets called accordingly

Jeremy

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Doug Hill

> On Jul 12, 2017, at 2:57 PM, Jeremy Hughes  
> wrote:
> 
>> On 12 Jul 2017, at 22:07, Quincey Morris 
>>  wrote:
>> 
>>> Or there's something else going on under the covers.
>> 
>> Yes, you are correct, betting *against* this assumption is a really, really 
>> terrible idea. Reasoning about the point at which objects actually 
>> deallocate is a code smell.
> 
> I’m trying to understand memory management so I can avoid retain cycles and 
> other issues.
> 
> …
> 
> If I release the child view controllers of this top-level view controller (by 
> assigning an empty array to childViewControllers), my expectation is that I 
> don’t have to release every view controller and view in the hierarchy because 
> they are effectively owned by the top-level view controller.

While this discussion has been good at understanding underlying ARC and manual 
ref-count issues, my guess as to what's causing these issues is that you 
shouldn't just assign nil to the childViewControllers array. You should try 
calling:

childVC.removeFromParentViewController()

for each child view controller.

Hopefully this is the source of your object-ownership issues.

Doug Hill

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Jeremy Hughes
> On 12 Jul 2017, at 22:07, Quincey Morris 
>  wrote:
> 
>> Or there's something else going on under the covers.
> 
> Yes, you are correct, betting *against* this assumption is a really, really 
> terrible idea. Reasoning about the point at which objects actually deallocate 
> is a code smell.

I’m trying to understand memory management so I can avoid retain cycles and 
other issues.

I have a view hierarchy that is constructed programmatically.

This involves creating a view controller and a view, and then creating child 
view controllers and views in a tree hierarchy. Child view controllers are 
added to parent view controllers - so that (as I understand it) the parent view 
controller owns the child view controller. Each view controller is given a 
view, which it presumably owns, and each view is attached to a superview, which 
also (presumably) owns the child view. So a view is owned by its view 
controller and by its superview.

There is also a top-level view controller that comes from a nib.

If I release the child view controllers of this top-level view controller (by 
assigning an empty array to childViewControllers), my expectation is that I 
don’t have to release every view controller and view in the hierarchy because 
they are effectively owned by the top-level view controller.

But I don’t have years of Cocoa and ARC experience, so it’s possible that I’m 
wrong.

Hence the reasoning.

Jeremy

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Jeremy Hughes
Thanks for elucidating!

> On 12 Jul 2017, at 22:03, Greg Parker  wrote:
> 
> ARC does add an optimization where a cooperating caller and callee can safely 
> avoid the retain/release pair around the return operation, effectively 
> transforming that call into the return-retained convention.

So in my original example, autorelease is optimised away when dealing with 
native Swift objects, but not when dealing with Cocoa objects?

Jeremy
___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Charles Srstka
> On Jul 12, 2017, at 1:24 PM, Jens Alfke  wrote:
> 
>> On Jul 12, 2017, at 10:38 AM, Charles Srstka > > wrote:
>> 
>> While that’s true, the main reason, as I understand it, that ARC doesn’t 
>> know enough about the object’s lifetime is that non-ARC code may be calling 
>> the method. In an all-ARC world, a method could always just return objects 
>> with a +1 retain count, and the consumer could just assume that and always 
>> balance the retain.
> 
> It could, but that results in _enormous_ numbers of retain/release calls. (I 
> speak from some experience, having once worked on performance optimization of 
> a project that did ref-counting this way.)
> 
> It’s generally cheaper overall to use autorelease, and that was one of the 
> reasons NeXT invented it* (besides the obvious benefit of simplifying MRR 
> code.)
> 
> —Jens
> 
> * I’m not actually sure they did; there’s an earlier technique called 
> “deferred reference counting” that might be equivalent.

How do you figure? Objects start with a +1 retain count, so returning that 
object with a +1 requires no retain/release calls at all; just return the 
thing. The client, in an all-ARC world, can then just assume the thing is +1 
and use it without needing to retain.

Objective-C ARC actually attempts to approximate this by peeking up the stack 
to see if the caller is ARC, in which case it skips the whole 
retain/autorelease dance and returns the object as is. But this is apparently 
not foolproof, since I often see autorelease calls showing up in Instruments in 
ARC apps, and even when it does work, the lookup process is still going to be 
more expensive than just returning the object.

Charles

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Quincey Morris
On Jul 12, 2017, at 13:59 , Steve Christensen  wrote:
> 
> It's also possible that, as an implementation detail, AppKit isn't 
> disconnecting the view controller's view from the view hierarchy until it 
> gets around to doing all the other view processing like redraws. If so then 
> the view could be holding on to its view controller until that time.

In principle, this kind of reasoning is correct. In fact, view controllers are 
unusual that none of the standard Cocoa components hold strong references to 
them (in 10.12+ they are in the responder chain, but I assume these are 
unretained references), except the parent view controller when there is a 
containment hierarchy.

> Or there's something else going on under the covers.

Yes, you are correct, betting *against* this assumption is a really, really 
terrible idea. Reasoning about the point at which objects actually deallocate 
is a code smell.

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Greg Parker

> On Jul 12, 2017, at 11:24 AM, Jens Alfke  wrote:
> 
>> On Jul 12, 2017, at 10:38 AM, Charles Srstka  
>> wrote:
>> 
>> While that’s true, the main reason, as I understand it, that ARC doesn’t 
>> know enough about the object’s lifetime is that non-ARC code may be calling 
>> the method. In an all-ARC world, a method could always just return objects 
>> with a +1 retain count, and the consumer could just assume that and always 
>> balance the retain.
> 
> It could, but that results in _enormous_ numbers of retain/release calls. (I 
> speak from some experience, having once worked on performance optimization of 
> a project that did ref-counting this way.)
> 
> It’s generally cheaper overall to use autorelease, and that was one of the 
> reasons NeXT invented it* (besides the obvious benefit of simplifying MRR 
> code.)

Autoreleasing return values by itself has no net effect on the number of 
retain/release operations compared to a scheme where return values are returned 
retained. In both cases there is a retain/release pair bracketing the return. 
In both cases an optimized function that is merely passing a returned value 
along can do so with no additional cost.

The benefit of the autoreleasing convention comes when you can return an 
unretained value without a retain/autorelease pair, because you "know" that the 
object will live long enough for the callee to use it. This does in fact avoid 
lots of retain/release pairs in carefully written code.

One cost of the autoreleasing convention is the autorelease pools themselves. 
Sometimes large numbers of otherwise-dead objects are kept alive by an 
autorelease pool.

Another cost of the autoreleasing convention is the bugs introduced when you 
"know" that an object can be safely returned unretained but you are wrong. The 
traditional example is -[NSMutableArray objectAtIndex:]. It returns the array 
value unretained with no retain/autorelease. This is fine while the array 
continues to hold the value, but can fail if the array is destroyed or the 
object is removed from the array.

ARC always retains and autoreleases when returning, for compatibility with 
non-ARC code. For safety reasons ARC never returns a bare unretained value and 
it always retains values that are returned to it. ARC does add an optimization 
where a cooperating caller and callee can safely avoid the retain/release pair 
around the return operation, effectively transforming that call into the 
return-retained convention.


> * I’m not actually sure they did; there’s an earlier technique called 
> “deferred reference counting” that might be equivalent.

Deferred reference counting is not much like autorelease. The goal of deferred 
RC is to accumulate many retain and release operations from a single thread and 
apply them all at once, in the hopes of reducing the cost of repeated refcount 
operations on a single object. It can be used with any parameter passing 
convention.


-- 
Greg Parker gpar...@apple.com  Runtime 
Wrangler


___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Steve Christensen
On Jul 12, 2017, at 1:16 PM, Jeremy Hughes  wrote:
> 
>> On 12 Jul 2017, at 19:25, Jens Alfke  wrote:
>> 
>>> 
>>> On Jul 12, 2017, at 10:57 AM, Jeremy Hughes  
>>> wrote:
>>> 
>>> Wouldn’t it be ARC (rather than the consumer) that is balancing retains?
>> 
>> Yes. ARC internally generates calls to -autorelease (or actually to some C 
>> functions in the runtime that invoke autorelease.)
> 
> Well, my original example was of native Swift objects that are released 
> instantly and Cocoa objects that are not, and you suggested that the Cocoa 
> objects are using autorelease - which makes sense, because Cocoa has to 
> support ARC and non-ARC code.
> 
> Is there any evidence that ARC is internally generating autorelease calls for 
> native Swift code?

It's also possible that, as an implementation detail, AppKit isn't 
disconnecting the view controller's view from the view hierarchy until it gets 
around to doing all the other view processing like redraws. If so then the view 
could be holding on to its view controller until that time. Or there's 
something else going on under the covers.

Unless it's really important for you to expect that the child view controller 
has disappeared immediately then it's probably better just to assume that it 
has (or will) and move on to other things.

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Jeremy Hughes
> On 12 Jul 2017, at 19:24, Jens Alfke  wrote:
> 
>> While that’s true, the main reason, as I understand it, that ARC doesn’t 
>> know enough about the object’s lifetime is that non-ARC code may be calling 
>> the method. In an all-ARC world, a method could always just return objects 
>> with a +1 retain count, and the consumer could just assume that and always 
>> balance the retain.
> 
> It could, but that results in _enormous_ numbers of retain/release calls. (I 
> speak from some experience, having once worked on performance optimization of 
> a project that did ref-counting this way.)

But an ARC compiler is smart enough to optimise these calls out of existence 
(in many cases).

Jeremy

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Jeremy Hughes
> On 12 Jul 2017, at 19:25, Jens Alfke  wrote:
> 
>> 
>> On Jul 12, 2017, at 10:57 AM, Jeremy Hughes  
>> wrote:
>> 
>> Wouldn’t it be ARC (rather than the consumer) that is balancing retains?
> 
> Yes. ARC internally generates calls to -autorelease (or actually to some C 
> functions in the runtime that invoke autorelease.)

Well, my original example was of native Swift objects that are released 
instantly and Cocoa objects that are not, and you suggested that the Cocoa 
objects are using autorelease - which makes sense, because Cocoa has to support 
ARC and non-ARC code.

Is there any evidence that ARC is internally generating autorelease calls for 
native Swift code?

Jeremy

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Jens Alfke

> On Jul 12, 2017, at 10:57 AM, Jeremy Hughes  
> wrote:
> 
> Wouldn’t it be ARC (rather than the consumer) that is balancing retains?

Yes. ARC internally generates calls to -autorelease (or actually to some C 
functions in the runtime that invoke autorelease.)

—Jens
___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Jens Alfke

> On Jul 12, 2017, at 10:38 AM, Charles Srstka  wrote:
> 
> While that’s true, the main reason, as I understand it, that ARC doesn’t know 
> enough about the object’s lifetime is that non-ARC code may be calling the 
> method. In an all-ARC world, a method could always just return objects with a 
> +1 retain count, and the consumer could just assume that and always balance 
> the retain.

It could, but that results in _enormous_ numbers of retain/release calls. (I 
speak from some experience, having once worked on performance optimization of a 
project that did ref-counting this way.)

It’s generally cheaper overall to use autorelease, and that was one of the 
reasons NeXT invented it* (besides the obvious benefit of simplifying MRR code.)

—Jens

* I’m not actually sure they did; there’s an earlier technique called “deferred 
reference counting” that might be equivalent.
___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Alex Zavatone
I used them in 2012 when dealing with capturing AV input from the front and 
back cameras on iDevices with ARC code.

IIRC, they were in the Apple sample code.





> On Jul 12, 2017, at 11:54 AM, Jeremy Hughes  
> wrote:
> 
>> On 12 Jul 2017, at 17:41, Jens Alfke  wrote:
>> 
>> There may still be a reference in the autorelease pool. Check childReference 
>> again ‘later’, i.e. on the next user event or after a timer/delayed-perform.
> 
> Thanks.
> 
> I’d forgotten about autorelease pools - but I guess they’re still there in 
> Cocoa for backwards compatibility with pre-ARC code.
> 
> Jeremy
> ___
> 
> 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:
> https://lists.apple.com/mailman/options/cocoa-dev/zav%40mac.com
> 
> This email sent to z...@mac.com

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Jeremy Hughes
> On 12 Jul 2017, at 18:38, Charles Srstka  wrote:
> 
>> On Jul 12, 2017, at 12:23 PM, Jens Alfke  wrote:
>> 
>>> On Jul 12, 2017, at 9:54 AM, Jeremy Hughes  
>>> wrote:
>>> 
>>> I’d forgotten about autorelease pools - but I guess they’re still there in 
>>> Cocoa for backwards compatibility with pre-ARC code.
>> 
>> Autorelease is still necessary with ARC. There are cases where ARC doesn’t 
>> know enough about object lifetimes at compile-time, and has to e.g. 
>> autorelease a temporary object before returning it from a method.
> 
> While that’s true, the main reason, as I understand it, that ARC doesn’t know 
> enough about the object’s lifetime is that non-ARC code may be calling the 
> method. In an all-ARC world, a method could always just return objects with a 
> +1 retain count, and the consumer could just assume that and always balance 
> the retain.

Wouldn’t it be ARC (rather than the consumer) that is balancing retains?

I’ve never used autorelease in native Swift code.

Jeremy

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Charles Srstka
> On Jul 12, 2017, at 12:23 PM, Jens Alfke  wrote:
> 
> 
>> On Jul 12, 2017, at 9:54 AM, Jeremy Hughes  
>> wrote:
>> 
>> I’d forgotten about autorelease pools - but I guess they’re still there in 
>> Cocoa for backwards compatibility with pre-ARC code.
> 
> Autorelease is still necessary with ARC. There are cases where ARC doesn’t 
> know enough about object lifetimes at compile-time, and has to e.g. 
> autorelease a temporary object before returning it from a method.

While that’s true, the main reason, as I understand it, that ARC doesn’t know 
enough about the object’s lifetime is that non-ARC code may be calling the 
method. In an all-ARC world, a method could always just return objects with a 
+1 retain count, and the consumer could just assume that and always balance the 
retain.

Charles

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Jens Alfke

> On Jul 12, 2017, at 9:54 AM, Jeremy Hughes  
> wrote:
> 
> I’d forgotten about autorelease pools - but I guess they’re still there in 
> Cocoa for backwards compatibility with pre-ARC code.

Autorelease is still necessary with ARC. There are cases where ARC doesn’t know 
enough about object lifetimes at compile-time, and has to e.g. autorelease a 
temporary object before returning it from a method.

—Jens
___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Jeremy Hughes
> On 12 Jul 2017, at 17:41, Jens Alfke  wrote:
> 
> There may still be a reference in the autorelease pool. Check childReference 
> again ‘later’, i.e. on the next user event or after a timer/delayed-perform.

Thanks.

I’d forgotten about autorelease pools - but I guess they’re still there in 
Cocoa for backwards compatibility with pre-ARC code.

Jeremy
___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Who owns a child view controller?

2017-07-12 Thread Jens Alfke

> On Jul 12, 2017, at 9:34 AM, Jeremy Hughes  
> wrote:
> 
> // Prints "Why is childReference not nil?”

There may still be a reference in the autorelease pool. Check childReference 
again ‘later’, i.e. on the next user event or after a timer/delayed-perform.

—Jens
___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Who owns a child view controller?

2017-07-12 Thread Jeremy Hughes
I’m trying to understand who owns a child view controller after it has been 
removed from its parent view controller.

The following code (which doesn’t involve view controllers) behaves as I would 
expect:

import Cocoa

class Element
{
var children = [Element]()
weak var parent: Element?

func addChild(_ child: Element)
{
children.append(child)
child.parent = self
}
}

let parent = Element()
var child: Element? = Element()
weak var childReference: Element? = child

parent.addChild(child!)

child = nil

parent.children = []

if childReference == nil
{
print("OK")
}
else
{
print(“Why is childReference not nil?”
}

// Prints “OK"

But if I replace Element with NSViewController, it behaves differently:

import Cocoa

let parent = NSViewController()
var child: NSViewController? = NSViewController()
weak var childReference: NSViewController? = child

parent.addChildViewController(child!)

child = nil

parent.childViewControllers = []

if childReference == nil
{
print("childReference is nil")
}
else
{
print("Why is childReference not nil?") 
}

// Prints "Why is childReference not nil?”

Jeremy

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com