Re: document-scoped bookmark

2017-07-14 Thread J.E. Schotsman

> On 14 Jul 2017, at 22:20, Quincey Morris 
>  wrote:
> 
> On Jul 14, 2017, at 11:57 , J.E. Schotsman  wrote:
>> 
>> I want to create document-scoped security bookmarks.
>> However, there seems to be no API for this.
> 
> Huh? It’s described here:
> 
> https://developer.apple.com/library/content/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW16
> 
> (under the heading “Security-Scoped Bookmarks and Persistent Resource 
> Access”), plus this:
> 
> https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW18
> 
> (“Enabling Security-Scoped Bookmark and URL Access”)

I had read all that, Quincey.
I decided to have a close look at the documentation for the

bookmarkData(options: NSURL.BookmarkCreationOptions = [], 
includingResourceValuesForKeys keys: [URLResourceKey]?, relativeTo relativeURL: 
URL?)

URL method and there it is:

“” relativeURL
The URL that the bookmark data will be relative to.
If you are creating a security-scoped bookmark to support App Sandbox, use this 
parameter as follows:
• To create an app-scoped bookmark, use a value of nil. 
• To create a document-scoped bookmark, use the absolute path (despite 
this parameter’s name) to the document file that is to own the new 
security-scoped bookmark. “"

Weird.
I am going to try it tomorrow.

Jan E.


___

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 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: document-scoped bookmark

2017-07-14 Thread Quincey Morris
On Jul 14, 2017, at 11:57 , J.E. Schotsman  wrote:
> 
> I want to create document-scoped security bookmarks.
> However, there seems to be no API for this.

Huh? It’s described here:

https://developer.apple.com/library/content/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW16
 


(under the heading “Security-Scoped Bookmarks and Persistent Resource Access”), 
plus this:

https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW18
 


(“Enabling Security-Scoped Bookmark and URL Access”)

___

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


document-scoped bookmark

2017-07-14 Thread J.E. Schotsman
Hello,

I want to create document-scoped security bookmarks.
However, there seems to be no API for this.

On StackOverflow I’ve found two conflicting views:
1. Too bad, never implemented by Apple
2. Create the bookmark relative to the document.

Can somebody please shed some light on this?

TIA,

Jan E.
___

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