Re: Need for Swift

2019-10-15 Thread Jeremy Hughes via Cocoa-dev
> On 15 Oct 2019, at 18:27, Turtle Creek Software via Cocoa-dev 
>  wrote:
> 
> MVC is an excellent design paradigm.  The M and V layers were no problem at
> all to set up. The C started out easy, but ended up being a big problem.
> Quite a bit of the business logic is not just data, but fancy stuff that
> happens with the GUI. Fields that switch between % and $, table cells that
> change other table cells, etc. There is a lot of code in our C++
> RecordViewer classes to make that happen, and it didn't integrate easily
> with NSWindowControllers or NSViewControllers.  It often was faster to just
> redo the logic in Cocoa.  That took a lot of time. Much more rewriting than
> expected.

If the RecordViewer is a controller of some kind, could you not add it to a 
view controller, and let the view controller (an ObjC++ subclass of 
NSViewController) call the RecordViewer to make these changes?

It sounds like you actually made quite a bit of progress if you’ve already 
rewritten the View (V) layers, and the Model (M) layer is separate.

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: Need for Swift

2019-10-15 Thread Jeremy Hughes via Cocoa-dev
Maybe it’s also worth noting that WebKit (the browser engine used by Safari) is 
written in C++

Safari’s UI is probably written in Obj-C(++) or a mixture of Obj-C(++) and 
Swift.

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: Thoughts on Cocoa

2019-10-04 Thread Jeremy Hughes via Cocoa-dev
> On 4 Oct 2019, at 11:43, Dragan Milić via Cocoa-dev 
>  wrote:
> 
>> pet 04.10. 2019., at 11.51, Jeremy Hughes via Cocoa-dev wrote:
>> 
>> It wasn’t clear to us (outside Apple) that Carbon was a temporary API until 
>> 2007, when Apple suddenly abandoned 64-bit Carbon.
> 
> I don’t agree.

Maybe it was clear to you, but it wasn’t clear to us. The company I work for 
sent developers to WWDC, and the message they came back with was that Carbon 
was a serious alternative to Cocoa. Of course, Apple changed its plans several 
times during this period, but the abandonment of 64-bit Carbon - after it had 
already been developed - was sudden and unexpected (to us).

It’s ancient history now. I wish Apple had given a clearer message and provided 
an easier transition. Carbon provided an easy way to transition from classic 
macOS, but there wasn’t an easy way to transition from Carbon to Cocoa.

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: Thoughts on Cocoa

2019-10-04 Thread Jeremy Hughes via Cocoa-dev
Hi Jens,

> On 3 Oct 2019, at 20:04, Jens Alfke via Cocoa-dev  
> wrote:
> 
> The people I hear complaining about this are those who, like you, didn't move 
> to Cocoa. Carbon was a _temporary_ transition API*. 

It wasn’t clear to us (outside Apple) that Carbon was a temporary API until 
2007, when Apple suddenly abandoned 64-bit Carbon.

That might have been a good decision from Apple’s perspective, but we found it 
was extremely difficult to convert a large Carbon (C++) program into a Cocoa 
(C++ / ObjC) program. We attempted to do this (starting in 2007) and we failed. 
There were various reasons for this failure - but in the end (starting in 2017) 
we decided to do a complete rewrite using Cocoa and Swift.

I know there are large companies that successfully moved from Carbon to Cocoa, 
including Apple itself. iTunes and the Finder became Cocoa programs at some 
point. But I don’t think it was easy for small companies with large/complex 
programs.

Personally, I think that Cocoa is a much better framework than Carbon ever was. 
But I wish that Apple had made it easier to transition from Carbon to Cocoa.

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: printing black

2019-01-22 Thread Jeremy Hughes
> On 22 Jan 2019, at 18:23, Alastair Houghton  
> wrote:
> 
> There’s often a printer setting on users’ printers to tell them to use (just) 
> black ink.

This also shows up in Cocoa Print dialogs under “Printer features” or as a 
“Greyscale” checkbox. I have it turned on by default.

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: Carbon -> Cocoa

2018-08-17 Thread Jeremy Hughes
> Of course, the C++ business logic doesn't need any changes.  The concern is,
> how long will it last?  Seems like the future is an entirely Swift-based API
> that replaces Objective-C Cocoa in 5 years, with no easy way to link to other 
> languages.

Core parts of Webkit are written in C++, so I think you’re safe with that.

I haven’t tried to interface between Swift and C++, but I think it’s possible 
and will probably get easier. You could ask in the Swift forums.

I think ObjC will be around for a while, at least the next ten years.

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: Carbon -> Cocoa

2018-08-17 Thread Jeremy Hughes
> Our app has 6 or 8 programmer-years of C++ cross-platform business logic.  
> Accounting software is complicated. Rewriting that in another language would 
> be hard work, and tons of testing. More than Mac sales would justify, so it 
> would be time to go Windows-only or just fold.

If you have a cross-platform business logic, it’s presumably separate from the 
UI and separate from Carbon - so you don’t need to rewrite it.

Personally, I would rewrite the UI. You can try to Cocoa-fy it in a gradual 
process, but that didn’t work out for us, and it doesn’t seem like it’s working 
out for you.

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: Carbon -> Cocoa

2018-08-16 Thread Jeremy Hughes
> By now, Cocoa may be the new Carbon.

The crucial difference is that Cocoa supports 64-bit applications, and Carbon 
doesn’t.

> If you haven't switched to Cocoa after all these years, and if your app is 
> large, I'd wait to see what happens with Marzipan


We don’t have time to wait for Marzipan - Apple are dropping support for 32-bit 
applications after Mojave.

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: Carbon -> Cocoa

2018-08-16 Thread Jeremy Hughes
We found it very difficult. This was for a large C++ Carbon application.

We’re now rewriting in Swift + Cocoa, starting from scratch.

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: Persistent User Defaults

2018-04-30 Thread Jeremy Hughes
Killing cfprefsd seems unnecessarily drastic. Why not use:

defaults delete 

as Gary Wade mentioned earlier?

 is a reverse-dns string such as “com.company.appname”

—

> On 30 Apr 2018, at 15:31, Alex Zavatone  wrote:
> 
> Is it worth it (or wise) to zero out preferences and write them prior to 
> performing a kill?
> 
>> On Apr 30, 2018, at 4:52 AM, Nathan Day  wrote:
>> 
>> Thats not completely correct modifying the preferences file directly or 
>> deleting it can take a while for the user defaults process to pick up the 
>> change, but you can force the user defaults process to pick up the changes 
>> with
>> 
>> killall cfprefsd
>> 
>> it can be a little bit complicated sometimes and the process can write out 
>> changes before you kill it, so sometime you have to kill make you change and 
>> then kill again.
>> 
>> 
>> 
>>> On 25 Apr 2018, at 3:42 am, Richard Charles  wrote:
>>> 
>>> On macOS an applications user defaults are stored in a preference plist 
>>> file located in ~/Library/Preferences.
>>> 
>>> If this file is deleted, user preferences for the application still persist 
>>> until the machine is rebooted. In other words if you want to start with a 
>>> clean set of user preferences not only must you delete the preference plist 
>>> file but you must also restart the machine.
>> 
>> ___
>> 
>> 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/moon.rabbit%40virginmedia.com
> 
> This email sent to moon.rab...@virginmedia.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: Size of compiled NIBs in Xcode 9 (10.13 SDK)

2018-01-24 Thread Jeremy Hughes
> On 24 Jan 2018, at 19:46, Dragan Milić  wrote:
> 
> BTW, in both cases (Xcode 9 - 10.13 SDK and Xcode 8 - 10.12 SDK) the 
> deployment target is macOS 10.11, so I don't think that setting matters.

Vince has explained why it does matter.

If you change the deployment target to 10.13 (which you probably don’t want to 
do) the application icons should no longer be duplicated. They’re currently 
being duplicated for backwards compatibility with old systems.

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: Size of compiled NIBs in Xcode 9 (10.13 SDK)

2018-01-24 Thread Jeremy Hughes
> I posted a related question in https://apple-dev.groups.io/g/xcode/ 
> ("Assets.car is much larger for High Sierra builds”) but I didn’t get much in 
> the way of a reply.

https://apple-dev.groups.io/g/xcode/message/396

> It seems that Assets.car is much larger when it is built with the 10.13 SDK 
> than when it is built with the 10.12 SDK.
> 
> I don’t know why.
> 
> 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: Size of compiled NIBs in Xcode 9 (10.13 SDK)

2018-01-24 Thread Jeremy Hughes
I posted a related question in https://apple-dev.groups.io/g/xcode/ 
("Assets.car is much larger for High Sierra builds”) but I didn’t get much in 
the way of a reply.

It seems that Assets.car is much larger when it is built with the 10.13 SDK 
than when it is built with the 10.12 SDK.

I don’t know why.

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: Scroll views

2018-01-20 Thread Jeremy Hughes
Hi Quincey,

I saw Kyle Sluder’s post some time ago, but it’s quite old and I’m not sure how 
relevant it is now. My complaint about scroll views is not that they don’t 
work, but that they’re confusing and I struggle each time I use them. My 
initial email was an attempt to summarise what I’ve discovered (so that it 
might be easier next time) and perhaps elicit helpful insights.

One of the things I’ve discovered is that you don’t have to fight the 
auto-resizing constraints that Apple adds by default. If you’re using actual 
constraints further down the view hierarchy, it’s much better to add explicit 
constraints to the “document” view - in which case the autoresize mask is 
removed and you don’t need to worry about it. Or if you’re adding a view from a 
nib, you can turn off autoresizing for this view (in IB or in code).

Placeholder constraints are useful in situations where IB doesn’t know about 
constraints that are added in code or in other views.

The solution that I have is working fine. I’ve used similar solutions in the 
past, and they’ve also worked fine - on different macOSes and with different 
versions of Xcode. The “problem” is that it seems like I have to go through a 
process of trial and error to rediscover this solution on each occasion, so 
I’ve been trying to consolidate my experience.

What I’m doing in a nutshell is:

1. Add explicit constraints to the “document” view so that the leading and 
trailing edges are pinned to the superview (i.e. the clip view). This prevents 
horizontal scrolling. This is similar to using an autoresize mask with the 
horizontal lines/arrows turned on, except that autoresizing will also generate 
additional constraints that conflict with explicit constraints in subviews.

2. Add placeholder constraints for the top and bottom edges. These aren’t 
needed as actual constraints (because the height of the “document" view is 
determined by a subview that is added in code) but they’re required in order to 
keep IB from complaining about missing constraints.

Thanks to your emails, I do now have a clearer idea of how to use constraints 
between the clip view and “document” view. I’d figured out by trial and error 
that I should use a placeholder constraint for the bottom edge (to allow 
scrolling), but your comments also prompted me to use a placeholder constraint 
for the top edge. This "makes sense" because you don’t logically want the top 
edge to be pinned to the clip view. (Still, it’s curious that everything still 
works if the top constraint is not a placeholder.)

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: Scroll views

2018-01-19 Thread Jeremy Hughes
> On 19 Jan 2018, at 22:15, Quincey Morris 
>  wrote:
> 
>> Interface Builder complains if I don’t also add vertical constraints, so 
>> I’ve done that, but made the bottom constraint into a placeholder (“Remove 
>> at build time”). Your email suggests that I can also make the top constraint 
>> into a placeholder. I’ve tried that now, and it seems to work fine. It also 
>> makes sense :)
> 
> Using placeholder constraints makes no sense to me.
> 
> First of all, you need to understand that in current versions of Xcode, IB 
> translates those resizing control arrows into constraints for you, unless you 
> add *explicit* constraints that it regards as overriding this “free” 
> translation. This means that those arrows are *not necessarily* honored. If 
> you’re getting messages about missing constraints, then that means you’ve 
> added some subview constraints that prevent the document view height 
> constraint from being inferred.

Once you add explicit constraints, IB turns off autoresizing altogether. The 
red arrows/lines disappear - there’s nothing there to be honoured or not 
honoured.

In my case, IB doesn’t know about the “document" height because it’s determined 
by a subview that is in a separate nib. That’s why I need to use placeholder 
constraints (otherwise IB complains about missing constraints). There are 
several subviews, and they are swapped in and out at runtime.

> — You don’t want IB to provide default constraints on the document view. You 
> should probably write code to remove any existing constraints from the 
> document view before you swap in new subviews. (Even if you turn off all the 
> arrows in the IB resize control, it’s not obvious to me that IB won’t add a 
> height constraint anyway.)

You don’t need to turn off the red arrows/lines because they disappear as soon 
as you add explicit constraints. Without autoresizing, IB doesn’t provide any 
default constraints. I don’t think you should ever have to remove default 
constraints in code - you should turn off autoresizing (in IB or in code) to 
prevent the default constraints from being created in the first place. 

I think I mentioned previously that constraints are added to the subviews at 
run time - and, yes, they are removed and recreated when subviews are swapped.

It is the subview that determines the width of the “document” view, so the 
horizontal (explicit) constraints pinning the “document” view to its superview 
are required. They perform the same task that the horizontal red arrows/lines 
do with autoresizing (prevent horizontal scrolling). I can’t use autoresizing 
here because it will create additional constraints that generate conflicts with 
subview constraints.

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


Scroll views and autolayout

2018-01-19 Thread Jeremy Hughes
This is a follow-up to my previous email on Scroll views.

What I actually want to is be able to swap different views (with different 
heights) in and out of the scroll view. To do this, I’m adding the different 
views as a subview of the “document" view (called contentParent below):

contentParent.subviews = [subview]

I then add constraints that pin the edges of this subview to the edges of its 
parent.

Unfortunately, this creates autolayout conflicts when autoresizing is used with 
contentParent, since the autoresizing mask has created a fixed height for 
contentParent, and this fails to match the height of the subview.

It seems that I can fix this by using autolayout on the document view 
(contentParent), so I’ve added constraints that pin the left, top, and right of 
contentParent to its superview. In order to keep IB happy I’ve also added a 
placeholder (“Remove at build time”) constraint that pins the bottom of 
contentParent to the bottom of its superview.

This seems to do what I want. I’m slightly concerned about the fact that the 
superview of contentParent is a clip view, because we don’t actually want the 
edges of contentParent to be pinned to the clip view (or it wouldn’t actually 
scroll within the clip view) - but I assume that there is some kind of magic 
that goes on behind the scenes when constraints are added to views that are 
enclosed within scroll/clip views (although I haven’t seen this discussed 
anywhere).

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


Scroll views

2018-01-19 Thread Jeremy Hughes
Does anyone understand scroll views? I struggle every time I use them, and it 
seems that I have to go through a process of trial and error to get them 
working properly.

If I drag a scroll view into another view in Interface Builder, I get a 
“Bordered Scroll View” that contains a “Clip View” that contains a “View” - 
which seems fine. The clip view will clip the content (“document”) view. So I 
can see what’s happening, I create a subclass for the document view, which 
looks like this (for debugging purposes):

class ContentView: NSView
{
//  override var isFlipped: Bool { return true }

override func draw(_ dirtyRect: NSRect)
{
super.draw(dirtyRect)

NSColor.red.set()
NSBezierPath.stroke(self.bounds)
}
}

isFlipped is commented out at this stage, but I’ve added it in case I need it 
later.

The document view’s class is set to ContentView in the Identity inspector in 
Interface Builder.

By default, Interface Builder gives the content/document view an autoresizing 
mask where all the red lines are turned on in the Size inspector - meaning that 
the width and height are flexible, and also (I think) that the margins are not 
flexible. What happens when I build and run without changing this is that the 
content view resizes to match the parent view - so the scroll view is 
completely redundant (nothing ever scrolls). That’s fine for horizontal 
scrolling, which I don’t want, but I do want to have vertical scrolling, so I 
turn off the adjustable height arrow.

What I now have is a view that scrolls vertically, but is pinned to the bottom 
of its parent view. Uncommenting isFlipped in ContentView fixes this problem, 
and I think everything is now working correctly. I’ve looked for a flipped 
setting in Interface Builder, but I haven’t found it, so I assume it’s missing 
for some reason that I don’t understand.

But there are other alternatives that seem confusing. Before turning on 
isFlipped in code, I tried turning off the bottom margin red line in Interface 
Builder. This gives me a view that is still pinned to the bottom of its parent 
view - but when the window is shrunk smaller than the height of the content 
view, the bottom rather than the top of the content view is scrolled out of 
view. If I turn isFlipped on at this point, I get a content view that is pinned 
to the top of its parent view (good), but when the window is shrunk smaller the 
top of the content view is scrolled out of view (not good). If I go back and 
turn the bottom red line back on and turn the top red line off (in IB), it 
works correctly.

Summarising: it seems that to get a vertically scrolling view that works as 
expected, the content view must be set to be flipped (no way of doing this in 
IB) and the flexible-height arrow must be turned off. The top-margin line can 
also be turned off, but it actually makes no difference if it is on or off.

Does anyone have a way to make sense of this or is it just inherently confusing?

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: Pasteboards and NSSecureCoding

2017-12-20 Thread Jeremy Hughes
Thanks for your detailed comments!

Something I’ve realised through this is that you need to be really careful 
about upgrading your system on a development machine. Going from 10.12 to 10.13 
- and finding that pasteboard functions compile just fine but no longer work - 
is almost as big a jump as going from Swift 3 to Swift 4.

I don’t think there's a non-hacky way to upgrade to a new system while 
continuing to use the previous SDK, but there should be! What I’d like is 
something similar to Swift transitions: Xcode could issue warnings and make 
similar helpful suggestions.

Jeremy

--

> On 20 Dec 2017, at 05:03, Quincey Morris 
>  wrote:
> 
> On Dec 19, 2017, at 18:32 , Jeremy Hughes  wrote:
>> 
>>> On 20 Dec 2017, at 02:22, Jeremy Hughes  wrote:
>>> 
>>> What I don’t like about [NSArray.self] is that it’s an artefact of 
>>> bridging. I’m not actually using it in the encoder:
>>> 
>>> coder.encode(arrayOfInts, forKey: kArrayKey)
>> 
>> The declaration:
>> 
>> encode(_ object: Any?, forKey key: String)
>> 
>> seems to indicate that it encodes any object
> 
> Yeah, you’re right, it’s secure on the decoding side only. 
> 
> This “encode” method is @objc, as I think you already noted, which AFAIK 
> means that if the value is an array, it’s going to be automatically bridged 
> to a NSArray. I would also expect it to become NSArray*, but I 
> can’t remember the rules, so I won’t go out on that limb. I also haven’t 
> looked at secure decoding recently, so I don’t know why or if the absence of 
> the element type matters when you’re securely decoding. It used to.
> 
> Note that the first parameter (“Any?”) doesn’t have to be an object in Swift, 
> although an object reference is required for the Obj-C method underneath. If 
> it’s a non-object in Swift, it’s actually passed as an opaque object that 
> wraps the Swift value.
> 
> After a while, you start to feel you need a ouija board to figure this stuff 
> out. As an alternative, if you are in control of both encoding and decoding, 
> and don’t need Obj-C compatibility inside the archive, you might do better to 
> use encode/decodeEncodable instead of encode/decodeObject. That takes type 
> bridging out of the picture, and trill preserves Swift types.
> 
> The last piece of this is that you should use one of the “decodeTopLevel…” 
> methods to decode the root object of your archive, for example 
> “decodeTopLevelDecodable(_:forKey:)”. This enables the relatively new — only 
> 5 years old! — failable decoding mechanism, where an error is thrown at the 
> top level if any of the decoding fails anywhere in the archive, 
> distinguishing failure from an init?(coder:) method that merely returns nil 
> to signify an optional value that isn’t present. (You use “failWithError” to 
> supply an error if you need to fail the decoding.)
> 
> Putting all that together, you can use NSKeyedArchiver/Unarchiver to encode 
> and decode more or less completely in the Swift domain (Codable), with proper 
> error handling and no obscure messing around with the types.

___

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: 10.13 printing problem

2017-12-19 Thread Jeremy Hughes
> On 19 Dec 2017, at 18:03, Jeremy Hughes  wrote:
> 
> I have a problem printing an autolayout view in 10.13.2, and I’m wondering if 
> there is something wrong with my code or if Apple broke something in 10.13 or 
> a more recent update.
> 
> I’m using the same view class for printing and screen, but I have a separate 
> view object for printing.
> 
> I’m overriding printOperation(withSettings)
> 
> This is how it works:
> 
> 1. Create the view
> 2. Set up and activate constraints
> 3. Call view.layoutSubtreeIfNeeded()
> 4. Return NSPrintOperation(view: view, printInfo: printInfo)
> 
> After (2) the view frame is empty.
> After (3) the view frame is set correctly in 10.12.6, but is empty in 10.13.2
> 
> One difference between print and screen views is that the print view doesn’t 
> have a superview, but it is constrained by its children, and I am actually 
> setting its width and height explicitly:
> 
> pageConstraints.append(NSLayoutConstraint(item: view, attribute: .width, 
> relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, 
> constant: viewWidth))
> 
> pageConstraints.append(NSLayoutConstraint(item: view, attribute: .height, 
> relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, 
> constant: viewHeight))
> 
> In 10.12.6, calling view.layoutSubtreeIfNeeded causes the view’s frame to be 
> set to {0, 0, viewWidth, viewHeight}
> In 10.13.2 this doesn’t happen
> 
> I can set the frame manually, but it seems wrong that I should have to do 
> this. The consequence of the frame not being set is that nothing is printed!

It seems wrong because you’re not supposed to have to set frames if you’re 
using auto layout.

> I don’t have previous versions of 10.13 that I can test on, so I don’t know 
> exactly when this got broken (or changed if it isn’t actually broken).

I think this is probably a bug in 10.13 (or 10.13.2), so maybe I should just 
file a bug report?

Unless someone can tell me why it isn’t a bug.

I can work around the problem by doing something like:

if view.frame.isEmpty
{
view.frame.origin = CGPoint(x: 0, y: 0)
view.frame.size = view.fittingSize 
}

after calling view.layoutSubtreeIfNeeded()

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: Pasteboards and NSSecureCoding

2017-12-19 Thread Jeremy Hughes
> On 20 Dec 2017, at 02:22, Jeremy Hughes  wrote:
> 
> What I don’t like about [NSArray.self] is that it’s an artefact of bridging. 
> I’m not actually using it in the encoder:
> 
> coder.encode(arrayOfInts, forKey: kArrayKey)

The declaration:

encode(_ object: Any?, forKey key: String)

seems to indicate that it encodes any object

But maybe it’s safe to assume that NSCoder will always encode/decode arrays as 
NSArrays, until it gets replaced with a Swift “Coder” class.

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: Pasteboards and NSSecureCoding

2017-12-19 Thread Jeremy Hughes
> On 20 Dec 2017, at 02:07, Quincey Morris 
>  wrote:
> 
> The class must be a kind of AnyClass, so you can’t specify a struct type. 
> Sorry I sent you off in the wrong direction on that.

That’s what I just concluded in an email I started writing.

>> The code I mentioned in my follow-up email seems to work:
>> 
>> let array = decoder.decodeObject(of: [NSArray.self], forKey: kArrayKey) as! 
>> [Int]
> 
> That will compile, but might not work. If you’re doing *secure* decoding then 
> the array of types must contain NSArray *and* the type of the elements in the 
> array. 
> 
> However, if you’re not doing secure decoding (and I don’t think you’re 
> required to, even if secure encoding was used to create the archive), then 
> [NSArray.self] should work.

It compiles and it seems to work. But, as I understand it, NSSecureCoding 
refers to decoding rather than encoding (there aren’t any special encoding 
functions) so I think I am doing secure decoding. I get an exception if I use 
an insecure decoding method, such as:

let array = decoder.decodeObject(forKey: kArrayKey) as! [Int]

What I don’t like about [NSArray.self] is that it’s an artefact of bridging. 
I’m not actually using it in the encoder:

coder.encode(arrayOfInts, forKey: kArrayKey)

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: Pasteboards and NSSecureCoding

2017-12-19 Thread Jeremy Hughes
> On 20 Dec 2017, at 01:25, Quincey Morris 
>  wrote:
> 
> You’ll have to figure out what type to use for the Ints. If they were 
> actually saved compatibly with Obj-C, the Ints will actually be NSNumbers, 
> and you’ll need to say “NSNumber.self”. If the Ints are stored opaquely as 
> Ints, I guess it would be Int.self. You should be able to figure out the 
> right type by trial and error, I’d say.
> 
> (Actually, if the array itself was saved opaquely, then you’ll need something 
> like [[Int].self], I guess. This is an area subject to automatic bridging, so 
> what you get depends on the exact code used to encode the archive.)

The array is saved as an array of Ints, not NSNumbers

coder.encode(arrayOfInts, forKey: kArrayKey)

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: Pasteboards and NSSecureCoding

2017-12-19 Thread Jeremy Hughes
Thanks, Quincey.

> That looks like Swift 3 code. The current version of the function is like 
> this:
> 
>> @nonobjc func decodeObject(of classes: [AnyClass]?, forKey key: String) -> 
>> Any?

@nonobjc means this is Swift-specfic then?

The init function I’m using is marked as @objc:

@objc required init(coder decoder: NSCoder)
{
}

> On 20 Dec 2017, at 01:25, Quincey Morris 
>  wrote:
> 
> so you’d specify [NSArray.self, .self] for the first parameter. 
> (Note, it’s a Swift-specific wrapper function, not just a direct API 
> translation.)
> 
> You’ll have to figure out what type to use for the Ints. If they were 
> actually saved compatibly with Obj-C, the Ints will actually be NSNumbers, 
> and you’ll need to say “NSNumber.self”. If the Ints are stored opaquely as 
> Ints, I guess it would be Int.self. You should be able to figure out the 
> right type by trial and error, I’d say.
> 
> (Actually, if the array itself was saved opaquely, then you’ll need something 
> like [[Int].self], I guess. This is an area subject to automatic bridging, so 
> what you get depends on the exact code used to encode the archive.)

let array = decoder.decodeObject(of: [[Int].self], forKey: kArrayKey) as! [Int]

gives an error:

Cannot invoke 'decodeObject' with an argument list of type '(of: [[Int].Type], 
forKey: String)’

The code I mentioned in my follow-up email seems to work:

let array = decoder.decodeObject(of: [NSArray.self], forKey: kArrayKey) as! 
[Int]

Presumably as! would throw an exception if it’s not an array of Ints, so that 
does get checked (and using as? with a failable initializer would presumably be 
better).

If I replace [NSArray.self] with [Array.self] I get an error:

Ambiguous reference to member 'decodeObject(of:forKey:)’

I’ve also tried [Array.self], which gives a different error:

Cannot invoke 'decodeObject' with an argument list of type '(of: 
[Array.Type], forKey: String)’

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: Pasteboards and NSSecureCoding

2017-12-19 Thread Jeremy Hughes
It seems that I can write:

let array = decoder.decodeObject(of: [NSArray.self], forKey: kArrayKey) as! 
[Int]

But shouldn't I be able to specify that this is an array of Ints, and not just 
an array of anything?

I should probably avoid force unwrapping - this ought to be a failable 
initializer, right?

Jeremy

--


> On 20 Dec 2017, at 01:09, Jeremy Hughes  wrote:
> 
> The release notes for 10.13 say:
> 
> If your application is linked on macOS 10.13 SDK or later, classes that 
> return NSPasteboardReadingAsKeyedArchive from 
> readingOptionsForType:pasteboard: must support secure coding, and will be 
> decoded with a coder that requires secure coding.
> 
> So I’m updating some of my classes to support NSSecureCoding, and I’m having 
> trouble figuring out how I should decode an array of Ints.
> 
> Previously, I had:
> 
> let array = decoder.decodeObject(forKey: kArrayKey) as! [Int]
> 
> I think that I need to replace that with something like:
> 
> let array = decoder.decodeObject(of: allowedClasses, forKey: kArrayKey) as! 
> [Int]
> 
> but I can’t work out how to define allowedClasses.
> 
> In a previous discussion, Quincey Morris wrote:
> 
>> The solution is to fall back to an explicit NSSet object:
>> 
>>  let classes = NSSet (objects: NSArray.self, MyElementClass.self)
>>  let myArray = coder.decodeObjectOfClasses (classes, forKey: “myArray”)
> 
> So I’ve tried:
> 
> let allowedClasses = NSSet(objects: NSArray.self, Int.self)
> 
> But I get an error: Cannot invoke 'decodeObject' with an argument list of 
> type '(of: NSSet, forKey: String)’
> 
> I also think there should be a way of doing this that uses Array and Set 
> rather than NSArray and NSSet
> 
> 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


Pasteboards and NSSecureCoding

2017-12-19 Thread Jeremy Hughes
The release notes for 10.13 say:

If your application is linked on macOS 10.13 SDK or later, classes that return 
NSPasteboardReadingAsKeyedArchive from readingOptionsForType:pasteboard: must 
support secure coding, and will be decoded with a coder that requires secure 
coding.

So I’m updating some of my classes to support NSSecureCoding, and I’m having 
trouble figuring out how I should decode an array of Ints.

Previously, I had:

let array = decoder.decodeObject(forKey: kArrayKey) as! [Int]

I think that I need to replace that with something like:

let array = decoder.decodeObject(of: allowedClasses, forKey: kArrayKey) as! 
[Int]

but I can’t work out how to define allowedClasses.

In a previous discussion, Quincey Morris wrote:

> The solution is to fall back to an explicit NSSet object:
> 
>   let classes = NSSet (objects: NSArray.self, MyElementClass.self)
>   let myArray = coder.decodeObjectOfClasses (classes, forKey: “myArray”)

So I’ve tried:

let allowedClasses = NSSet(objects: NSArray.self, Int.self)

But I get an error: Cannot invoke 'decodeObject' with an argument list of type 
'(of: NSSet, forKey: String)’

I also think there should be a way of doing this that uses Array and Set rather 
than NSArray and NSSet

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


10.13 printing problem

2017-12-19 Thread Jeremy Hughes
I have a problem printing an autolayout view in 10.13.2, and I’m wondering if 
there is something wrong with my code or if Apple broke something in 10.13 or a 
more recent update.

I’m using the same view class for printing and screen, but I have a separate 
view object for printing.

I’m overriding printOperation(withSettings)

This is how it works:

1. Create the view
2. Set up and activate constraints
3. Call view.layoutSubtreeIfNeeded()
4. Return NSPrintOperation(view: view, printInfo: printInfo)

After (2) the view frame is empty.
After (3) the view frame is set correctly in 10.12.6, but is empty in 10.13.2

One difference between print and screen views is that the print view doesn’t 
have a superview, but it is constrained by its children, and I am actually 
setting its width and height explicitly:

pageConstraints.append(NSLayoutConstraint(item: view, attribute: .width, 
relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, 
constant: viewWidth))

pageConstraints.append(NSLayoutConstraint(item: view, attribute: .height, 
relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, 
constant: viewHeight))

In 10.12.6, calling view.layoutSubtreeIfNeeded causes the view’s frame to be 
set to {0, 0, viewWidth, viewHeight}
In 10.13.2 this doesn’t happen

I can set the frame manually, but it seems wrong that I should have to do this. 
The consequence of the frame not being set is that nothing is printed!

I don’t have previous versions of 10.13 that I can test on, so I don’t know 
exactly when this got broken (or changed if it isn’t actually broken).

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: Is "-init" really needed?

2017-08-10 Thread Jeremy Hughes
> On 10 Aug 2017, at 15:15, Alastair Houghton  
> wrote:
> 
> On 10 Aug 2017, at 15:09, Charles Srstka  wrote:
>> 
>> They’re equivalent syntactically, but performance-wise, +array and friends 
>> will cause the object to be put into an autorelease pool. Therefore, +new is 
>> better for performance.
> 
> Not with ARC they don’t.  The ARC logic circumvents the autorelease pool in 
> that case.

Are you sure?

We had a discussion about autorelease pools recently, and it seems that they’re 
still used by Cocoa APIs (to support ARC and non-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-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 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 unwrapped optional in the Swift book 
exam

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:
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 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 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 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 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


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


Re: Calculating intrinsicContentSize for a NSTextField

2017-03-18 Thread Jeremy Hughes
> On 18 Mar 2017, at 04:45, Daryle Walker  wrote:
> 
>> This works, but if I remove the call to attributedStringValue (whose result 
>> is discarded) the result of the following line fails to reflect changes in 
>> the bounds of the text, and the field fails to grow or shrink.
>> 
>> Presumably, calling attributedStringValue has a side effect which changes 
>> the way that cellSize:forBounds: is calculated.
> 
> Looking at the “attributedStringValue” docs, "validate​Editing()” is called 
> as the side effect.

Thanks - that works, and the documentation explains why:

"Validation sets the object value of the cell to the current contents of the 
cell’s editor (the NSText object used for editing), storing it as a simple 
NSString or an attributed string object based on the attributes of the editor.”

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

Calculating intrinsicContentSize for a NSTextField

2017-03-17 Thread Jeremy Hughes
I have a text field that I want to grow and shrink while it is being edited.

In order to do that, I have overridden intrinsicContentSize and textDidChange 
in a subclass of NSTextField:

override var intrinsicContentSize: NSSize
{
if let cell = cell, cell.wraps
{
let size = CGSize(width: bounds.size.width, height: 
CGFloat.greatestFiniteMagnitude)

let _ = attributedStringValue

let cellSize = cell.cellSize(forBounds: CGRect(origin: 
CGPoint(), size: size))

return cellSize
}
else
{
return super.intrinsicContentSize
}
}

override func textDidChange(_ notification: Notification)
{
super.textDidChange(notification)

invalidateIntrinsicContentSize()
}

This works, but if I remove the call to attributedStringValue (whose result is 
discarded) the result of the following line fails to reflect changes in the 
bounds of the text, and the field fails to grow or shrink.

Presumably, calling attributedStringValue has a side effect which changes the 
way that cellSize:forBounds: is calculated.

Is there a way that I can get cellSize:forBounds: to return the correct value 
without relying on this side effect?

An alternative way of calculating the intrinsic content size would be to use:

attributedStringValue.boundingRect(with: size, options: .usesLineFragmentOrigin)

but this fails to take account of cell insets.

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: needsDisplay and subviews

2017-03-10 Thread Jeremy Hughes
> On 9 Mar 2017, at 18:32, corbin dunn  wrote:
> 
>> 
>> On Mar 8, 2017, at 8:46 AM, Jeremy Hughes  
>> wrote:
>> 
>> If needsDisplay is set to true for an NSView, does that also cause subviews 
>> to be redrawn?
>> 
>> I’ve seen conflicting statements about this, but haven’t found anything in 
>> Apple’s documentation.
> 
> Just to be clear: if you want a view to be redrawn you should call 
> setNeedsDisplay on that view. That’s really the bottom line. There are some 
> cases where AppKit will redraw subviews when a parent view is invalidated, 
> but you should not depend on this!

Thanks for being clear!

> I also don’t recommend things like this:
> 
>> override var needsDisplay: Bool
>> {
>>  willSet
>>  {
>>  for view in subviews
>>  {
>>  view.needsDisplay = newValue
>>  }
>>  }
> 
> 
> Instead, it is better if your subviews invalidate themselves when their state 
> changes.

In this case I have a view that is broken up into subviews but should really be 
treated as a single view as far as redraws are concerned. When the model object 
for the view changes, the entire view needs to be redrawn. The controller for 
this view is not aware of each individual subview or what kind of view it is 
dealing with - it’s actually dealing with a more general view that is a 
superclass of different kinds of specific views. Also, the views aren’t aware 
of model states, so they can’t invalidate themselves.

The willSet override isn’t a general override that will cause all views to 
redraw whenever a superview is redrawn. It’s a specific override for a 
particular view that is really a cluster of subviews and which needs all of its 
subviews to be redrawn whenever it is invalidated.

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: needsDisplay and subviews

2017-03-09 Thread Jeremy Hughes
> On 9 Mar 2017, at 10:24, Jeremy Hughes  wrote:
> 
> So it seems that for layer-backed views, setting needsDisplay does cause the 
> view to be redrawn - but the value is never actually set. If I needed to work 
> with layer-backed views, it might be possible to get around this by 
> overriding willSet instead of didSet.

I’ve now tried this, and it works.

To ensure that a subview will be redrawn when needsDisplay is (attempted to be) 
set on its superview we can add the following code:

override var needsDisplay: Bool
{
willSet
{
for view in subviews
{
view.needsDisplay = newValue
}
}
}

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: needsDisplay and subviews

2017-03-09 Thread Jeremy Hughes
> On 9 Mar 2017, at 01:49, Quincey Morris  
> wrote:
> 
> So, the correct answer to your original question, I think, is that if your 
> model data has changed in such a way that the representation in custom views 
> no longer reflects the data, then you should set “needsDisplay” on *every* 
> custom subview that uses “draw(_:)”.
> 
> If you just need your changed view to be re-composited with the same subview 
> contents as previously, then you don’t need to set “needsDisplay” on the 
> subviews, just the parent view.

OK - that disagrees with Ben’s conclusion:

"Thus, it seems to follow that so long a custom view's display() calls super, 
then all of its subviews should also be drawn when its needsDisplay is true.”

But maybe it is covered by the “as necessary” clause in Apple’s documentation:

display(): "Displays the view and all its subviews if possible, invoking each 
of the NSView methods lockFocus(), draw(_:), and unlockFocus() as necessary.”

I have a custom view that has two custom subviews, and is a subclass of a more 
general custom view. The code that tells the general (superclass) view that it 
needs to be redrawn shouldn’t have to know which kind of (subclass) view it is 
dealing with. So it would be necessary for the subclass view to override 
needsDisplay with an observer that sets needDisplay to be true for its subviews:

override var needsDisplay: Bool
{
didSet
{
for view in subviews
{
view.needsDisplay = needsDisplay
}
}
}

Currently, I don’t actually need to do this because I’m not trying to use 
layer-backed views (that happened accidentally through a bug or unexpected 
behaviour in Interface Builder), but the fact that Apple is unclear about how 
needsDisplay affects subviews means that I probably should do this in case they 
introduce new drawing optimisations in future versions of macOS.

The other puzzle in all this is why it should be the case that setting 
needsDisplay to be true on a layer-backed view actually doesn’t set it to be 
true:

> One other strange behaviour with the problem xib occurred when I added some 
> debugging code to try and find out why the subview wasn’t being redrawn:
> 
>   view.needsDisplay = true
>   print("view.needsDisplay: \(view.needsDisplay)”)
> 
> and this consistently printed “ view.needsDisplay: false” after 
> view.needsDisplay had been set to true. Despite this, “draw” (= drawRect in 
> ObjC) was being called for “view” - but not for view’s subviews.

Before I discovered that IB had changed one of my views to be layer-backed, I 
tried using the didSet observer to pass on needsDisplay to subviews and found 
that it was setting the value to be false for subviews when I had set it to be 
true for the superview (that’s why I added the debugging code above).

So it seems that for layer-backed views, setting needsDisplay does cause the 
view to be redrawn - but the value is never actually set. If I needed to work 
with layer-backed views, it might be possible to get around this by overriding 
willSet instead of didSet.

I think NSView needs a “Redraws subviews” property (similar to “Autoresizes 
subviews”) that will take away the guesswork and hackery that we currently need 
to use in order to get some kind of consistent behaviour.

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: needsDisplay and subviews

2017-03-08 Thread Jeremy Hughes
The situation in which subviews were not being redrawn seems to have been a xib 
problem. After spending some time getting nowhere I decided to recreate the xib 
by taking a different xib (which used the same custom view) and cutting it 
down. This worked without any problems. Then I compared the two xibs in 
TextWrangler and found that the one which didn’t work had a view where 
“wantsLayer” was set to YES - and this corresponded to a “Core Animation Layer” 
checkbox in Interface Builder.

I didn’t intentionally select this checkbox, and I didn’t originally look at 
this pane (View Effects) when I was trying to spot differences between the view 
that worked and the view that didn’t. But in my first attempt at creating this 
xib (where the problem occurred) I copied and pasted a view from another xib, 
whereas in my second attempt I duplicated the entire xib and modified it - so 
maybe the checkbox property was set as a side effect of copying and pasting.

One other strange behaviour with the problem xib occurred when I added some 
debugging code to try and find out why the subview wasn’t being redrawn:

view.needsDisplay = true
print("view.needsDisplay: \(view.needsDisplay)”)

and this consistently printed “ view.needsDisplay: false” after 
view.needsDisplay had been set to true. Despite this, “draw” (= drawRect in 
ObjC) was being called for “view” - but not for view’s subviews.

My conclusion (for now) is that “needsDisplay” causes subviews to be redrawn - 
except when “wantsLayer” has been set to true.

Does that make sense?

Jeremy

--

> On 8 Mar 2017, at 17:12, Jeremy Hughes  wrote:
> 
> Thanks - that seems reasonably clear, and it agrees with what I previously 
> thought, but I’ve got a situation where it doesn’t seem to be happening.
> 
> There are contradictory opinions on Stack Overflow: 
> 
> http://stackoverflow.com/questions/8718290/setneedsdisplay-and-subviews
> http://stackoverflow.com/questions/11480341/setneedsdisplay-does-not-trigger-drawrect-in-subviews-as-expected
> 
> Jeremy
> 
> --
> 
>> On 8 Mar 2017, at 17:01, Ben Kennedy  wrote:
>> 
>> 
>>> On 08 Mar 2017, at 8:46 am, Jeremy Hughes  
>>> wrote:
>>> 
>>> If needsDisplay is set to true for an NSView, does that also cause subviews 
>>> to be redrawn?
>> 
>> Admittedly I've been mostly doing iOS development for the last several years 
>> and barely any Mac lately, but, according to the current docs:
>> 
>> needsDisplay: "The displayIfNeeded methods check the value of this property 
>> to avoid unnecessary drawing, and all display methods set the value back to 
>> false when the view is up to date."
>> 
>> display(): "Displays the view and all its subviews if possible, invoking 
>> each of the NSView methods lockFocus(), draw(_:), and unlockFocus() as 
>> necessary."
>> 
>> Thus, it seems to follow that so long a custom view's display() calls super, 
>> then all of its subviews should also be drawn when its needsDisplay is true.
>> 
>> What sort of contradictions are out there?
>> 
>> b
>> 
> 


___

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

needsDisplay and subviews

2017-03-08 Thread Jeremy Hughes
If needsDisplay is set to true for an NSView, does that also cause subviews to 
be redrawn?

I’ve seen conflicting statements about this, but haven’t found anything in 
Apple’s documentation.

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: Binding NSTextField to an array

2017-03-06 Thread Jeremy Hughes
> On 6 Mar 2017, at 17:34, Jeremy Hughes  wrote:
> 
> It all works now.

Actually, it works as far as the text field displays “Multiple” (placeholder) 
for multiple values, but it doesn’t work when I set a value in the text field. 
In that case I get:

Error setting value for key path selection.self of object [object class: NSMutableDictionary, number of selected objects: 
2] (from bound object ): [<__NSCFNumber 0x337> 
setValue:forUndefinedKey:]: this class is not key value coding-compliant for 
the key self.

The text field is bound to an array of NSNumbers via an array controller (using 
a Swift array that is marked as “dynamic”)

I can get around this by writing a “Number” wrapper:

class Number: NSObject
{
dynamic var value: NSNumber

init(_ value: Int) { self.value = NSNumber(value: value) }
}

dynamic var values: [Number]

and binding the text field to the “value” field of this wrapper (so the 
controller key is arrayController.selection and the model key path is “value").

But I wonder if it is possible to bind directly to an array of NSNumbers 
without using a wrapper.

I’ve tried doing that using an array of NSNumbers with the model key path set 
to “value” (i.e. the value of the NSNumber) but I get the following error:

 [<__NSCFNumber 0x337> valueForUndefinedKey:]: this class is not key value 
coding-compliant for the key value.

So, unless there’s another key path I can use for NSNumber, I’m guessing it 
isn’t possible to do this.

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: Binding NSTextField to an array

2017-03-06 Thread Jeremy Hughes
Bingo and thanks!

I had already found the checkbox for “Selects All When Setting Content"

The missing piece of the jigsaw was using “selection" as the Controller Key and 
“self" as the Model Key Path.

It all works now.

Jeremy

--

> On 6 Mar 2017, at 17:12, Mike Abdullah  wrote:
> 
> Yep, you’re very close. An array controller is required indeed, it’s the one 
> responsible for vending out NSMultipleValuesMarker.
> 
> From your earlier message, you’re now seeing an exception or similar:
> Cannot create number from object <_NSControllerObjectProxy: 0x600070b0> 
> of class _NSControllerObjectProxy
> 
> This is because you’ve bound the field directly to the array controller’s 
> .selection property. .selection returns a proxy object representing the 
> selection which can then be queried for other properties. In your case you 
> want to bind to “selection.self” instead I believe.
> 
> When binding your array controller to its content, there’s also an option to 
> have it automatically select all (or something to that effect). You want to 
> have this turned on too so that the array controller has a selection to 
> generate values from.
> 
> Mike.
> 
>> On 6 Mar 2017, at 17:44, Jeremy Hughes  wrote:
>> 
>>> On 6 Mar 2017, at 14:30, Jonathan Mitchell  wrote:
>>> 
>>> Sounds like NSValueTransformer is in fact what you need.
>>> It can take in your NSArray ref and spit out a single NSString that the 
>>> NSTextField binding can live with.
>> 
>> I think I must be missing something obvious.
>> 
>> The value of an NSTextField can be bound (in Interface Builder) to a 
>> property in File’s Owner or to an array controller that is bound to a 
>> property in File’s Owner. There is a checkbox in Interface Builder that says 
>> “Allows Editing Multiple Values Selection”.
>> 
>> This suggests to me that I can bind a text field to an array or (if that's 
>> not possible) to an array controller that is bound to the array. If there 
>> are multiple values, the controller should return NSMultipleValuesMarker, 
>> which according to Apple’s documentation "indicates that more than one 
>> object is selected in the controller and the values for the requested key 
>> aren’t the same.”
>> 
>> The documentation goes on to say "For example, if the value for 
>> selection.name returns an array containing three strings—”Tony”, “Tony”, 
>> “Tony”—the string “Tony” is returned instead of the NSMultipleValuesMarker.”
>> 
>> What I’m trying to do is to display a textfield (with a number formatter) 
>> which should display an integer value (such as “7”) if all the values in the 
>> array are the same, or a multiple-values indicator (like “-“) if the values 
>> are not the same.
>> 
>> I can get the binding to work if I bind the text field to a single value, 
>> but I can’t get it to work with an array of values or with an array 
>> controller that is bound to an array of values.
>> 
>> Maybe I should give up on using bindings to do this, but it would be good to 
>> understand what I’m doing wrong.
>> 
>> 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/mabdullah%40karelia.com
>> 
>> This email sent to mabdul...@karelia.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: Binding NSTextField to an array

2017-03-06 Thread Jeremy Hughes
> On 6 Mar 2017, at 14:30, Jonathan Mitchell  wrote:
> 
> Sounds like NSValueTransformer is in fact what you need.
> It can take in your NSArray ref and spit out a single NSString that the 
> NSTextField binding can live with.

I think I must be missing something obvious.

The value of an NSTextField can be bound (in Interface Builder) to a property 
in File’s Owner or to an array controller that is bound to a property in File’s 
Owner. There is a checkbox in Interface Builder that says “Allows Editing 
Multiple Values Selection”.

This suggests to me that I can bind a text field to an array or (if that's not 
possible) to an array controller that is bound to the array. If there are 
multiple values, the controller should return NSMultipleValuesMarker, which 
according to Apple’s documentation "indicates that more than one object is 
selected in the controller and the values for the requested key aren’t the 
same.”

The documentation goes on to say "For example, if the value for selection.name 
returns an array containing three strings—”Tony”, “Tony”, “Tony”—the string 
“Tony” is returned instead of the NSMultipleValuesMarker.”

What I’m trying to do is to display a textfield (with a number formatter) which 
should display an integer value (such as “7”) if all the values in the array 
are the same, or a multiple-values indicator (like “-“) if the values are not 
the same.

I can get the binding to work if I bind the text field to a single value, but I 
can’t get it to work with an array of values or with an array controller that 
is bound to an array of values.

Maybe I should give up on using bindings to do this, but it would be good to 
understand what I’m doing wrong.

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: Binding NSTextField to an array

2017-03-06 Thread Jeremy Hughes
> From what I understand of your example, you’re not “binding” anything in a 
> Cocoa sense.

In the case of the single value, the text field is set up via the Bindings pane 
of Interface Builder so that “Value" says “Bind to File’s Owner” with a model 
key path of self.value. (And “value" is declared as dynamic so that Swift will 
take care of KVO.) This works fine. Is this not a Cocoa binding?

What I don’t understand is why this works for a single value but doesn’t work 
for an array of values, where I change the model key path to self.values.

> What you is an NSArrayController. Bind your text field to the array 
> controller. Supply the array controller with content, and have it derive the 
> selected value, be it single or multiple.

OK. I now have an array controller that is bound to File’s Owner with a model 
key path of self.values, and I then bind the text field to the array controller 
with a Controller Key value of “selection” (although I’m not sure that’s right, 
because the array is not actually displayed anywhere for users to select items).

Now I get the following error:

Cannot create number from object <_NSControllerObjectProxy: 0x600070b0> of 
class _NSControllerObjectProxy

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

Binding NSTextField to an array

2017-03-06 Thread Jeremy Hughes
Hi,

This seems like an elementary question.

I’d like to bind an NSTextField to an array of numerical values, so that the 
text field will either display a single value if the values are identical or 
will display a multiple values marker if the values are different.

Using Swift, I can bind a text field to a single value like this:

dynamic var value = NSNumber(value: 7)

But if I try to bind to an array of values like this:

dynamic var values = [NSNumber(value: 7), NSNumber(value: 3)]

I get the following error:

Cannot create number from object (
7,
3
) of class _TtGCs23_ContiguousArrayStorageCSo8NSNumber_

How do I bind an NSTextField to an array?

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: didPrint selector not called

2016-12-16 Thread Jeremy Hughes

> On 16 Dec 2016, at 21:54, Jeremy Hughes  wrote:
> 
>> In that case, you don’t know for sure who calls it and when. It appears to 
>> documented that it’s called as part of the standard implementation of 
>> “printDocument”, but you don’t know if there are other circumstances where 
>> it’s called from somewhere else.
>> 
>> AFAICT you are required to invoke the passed-in selector at the correct 
>> time. In your case, that’s in your own document:didPrint:contextInfo: 
>> method, and therefore (I think) is going to require an invocation because 
>> you can’t perform a selector with a non-object parameter. So, yes, you might 
>> have to write some Obj-C glue to do this properly.
>> 
>> My guess is that “doing it wrong” is going to be harmless in the case of 
>> regular printing from a menu, but it might break if (for example) 
>> AppleScript was involved, or something like that. Anyway, it’s your decision 
>> what to do. At least you’re aware of the possible issue now.
> 
> Thanks. I’ve given up on overriding printDocumentWithSettings and I’m now 
> overriding printDocument instead, following John’s suggestion.

You might say that this means I won’t be able to set a callback if 
printDocumentWithSettings is called from somewhere else (AppleScript or 
whatever).

All I’m trying to do is to clean up some objects which are no longer needed 
when the print operation is completed.

It’s not critical that this happens - the objects aren’t large, and if they 
don’t get cleaned up, they will be deallocated when the next print operation 
happens.

Maybe there’s an easier way to do this?

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: didPrint selector not called

2016-12-16 Thread Jeremy Hughes
> On 16 Dec 2016, at 21:40, Quincey Morris 
>  wrote:
> 
> On Dec 16, 2016, at 12:01 , Jeremy Hughes  wrote:
>> 
>> It’s just an application method, which overrides the method that the system 
>> calls from printDocument when a user chooses Print.
> 
> Just to be clear, does the “it” in that sentence refer to 
> “printDocumentWithSettings”?

Yes.

> In that case, you don’t know for sure who calls it and when. It appears to 
> documented that it’s called as part of the standard implementation of 
> “printDocument”, but you don’t know if there are other circumstances where 
> it’s called from somewhere else.
> 
> AFAICT you are required to invoke the passed-in selector at the correct time. 
> In your case, that’s in your own document:didPrint:contextInfo: method, and 
> therefore (I think) is going to require an invocation because you can’t 
> perform a selector with a non-object parameter. So, yes, you might have to 
> write some Obj-C glue to do this properly.
> 
> My guess is that “doing it wrong” is going to be harmless in the case of 
> regular printing from a menu, but it might break if (for example) AppleScript 
> was involved, or something like that. Anyway, it’s your decision what to do. 
> At least you’re aware of the possible issue now.

Thanks. I’ve given up on overriding printDocumentWithSettings and I’m now 
overriding printDocument instead, following John’s suggestion.

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: didPrint selector not called

2016-12-16 Thread Jeremy Hughes
> This is what I’ve currently got. It works OK, but the dictionary conversion 
> seems clunky to me.
> 
> override func printDocument(sender: AnyObject?)
> {
>   let didPrintSelector = #selector(document(_:didPrint:contextInfo:))
>   
>   let dictionary = printInfo.dictionary()
>   var printSettings = [String : AnyObject]()
>   
>   for key in printInfo.dictionary().allKeys
>   {
>   if let string = key as? String
>   {
>   printSettings[string] = dictionary.valueForKey(string)
>   }
>   }
>   
>   printDocumentWithSettings(printSettings, showPrintPanel: true, 
> delegate: self, didPrintSelector: didPrintSelector, contextInfo: nil)
> }

If I cast the NSMutableDictionary to an NSDictionary, I can recast that to a 
Swift dictionary:

override func printDocument(sender: AnyObject?)
{
let didPrintSelector = #selector(document(_:didPrint:contextInfo:))

let printSettings = (printInfo.dictionary() as NSDictionary) as! 
[String : AnyObject]

printDocumentWithSettings(printSettings, showPrintPanel: true, 
delegate: self, didPrintSelector: didPrintSelector, contextInfo: nil)
}

Is this a general thing? If I want to cast an NSMutableType to a Swift Type I 
have to cast it to an NSType first?

Maybe it's changed in Swift 3 (I’m still on 2.2) but I haven’t found any Apple 
documentation about this.

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: didPrint selector not called

2016-12-16 Thread Jeremy Hughes
> On 16 Dec 2016, at 20:17, Jeremy Hughes  wrote:
>>> I'm not an expert in this part of Cocoa.  Are there implicit system 
>>> *callers* of this method, or is it more of a system *utility* that you're 
>>> expected to call from your own code?  If it's the latter, then maybe 
>>> instead of overriding it you should just provide a different method that 
>>> calls it, doing whatever set up you need first and then passing in the 
>>> appropriate delegate and selector to do cleanup.
>> 
>> It’s just an application method, which overrides the method that the system 
>> calls from printDocument when a user chooses Print.

Less confusingly: it’s a Document (subclass of NSDocument) method

> I could override printDocument, but I’m not sure how to get the printSettings 
> that I need to pass through to printDocumentWithSettings. Looking at Apple's 
> documentation, I think I can get these by calling dictionary() on an 
> NSPrintInfo object. That returns an NSMutableDictionary, but the compiler 
> won’t let me use this as a printSettings argument:
> 
> "Cannot convert value of type 'NSMutableDictionary' to expected argument type 
> '[String : AnyObject]’"
> 
> Do I need to iterate through the NSMutableDictionary and create a Swift 
> Dictionary from it?
> 
> Maybe I’ve missed an easier way of doing this. All I want to happen is to be 
> notified when the print operation is completed.

This is what I’ve currently got. It works OK, but the dictionary conversion 
seems clunky to me.

override func printDocument(sender: AnyObject?)
{
let didPrintSelector = #selector(document(_:didPrint:contextInfo:))

let dictionary = printInfo.dictionary()
var printSettings = [String : AnyObject]()

for key in printInfo.dictionary().allKeys
{
if let string = key as? String
{
printSettings[string] = dictionary.valueForKey(string)
}
}

printDocumentWithSettings(printSettings, showPrintPanel: true, 
delegate: self, didPrintSelector: didPrintSelector, contextInfo: 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

Re: didPrint selector not called

2016-12-16 Thread Jeremy Hughes

> On 16 Dec 2016, at 20:01, Jeremy Hughes  wrote:
> 
>>> OK - I misunderstood what Quincey was saying.
>>> 
>>> The passed-in delegate and selector are nil, but I obviously can’t be sure 
>>> that they will always be nil.
>>> 
>>> All I’m actually trying to do is to clean up some objects that need to 
>>> exist during the print operation. Is this the best way for me to be doing 
>>> that?
>> 
>> I'm not an expert in this part of Cocoa.  Are there implicit system 
>> *callers* of this method, or is it more of a system *utility* that you're 
>> expected to call from your own code?  If it's the latter, then maybe instead 
>> of overriding it you should just provide a different method that calls it, 
>> doing whatever set up you need first and then passing in the appropriate 
>> delegate and selector to do cleanup.
> 
> It’s just an application method, which overrides the method that the system 
> calls from printDocument when a user chooses Print.

I could override printDocument, but I’m not sure how to get the printSettings 
that I need to pass through to printDocumentWithSettings. Looking at Apple's 
documentation, I think I can get these by calling dictionary() on an 
NSPrintInfo object. That returns an NSMutableDictionary, but the compiler won’t 
let me use this as a printSettings argument:

"Cannot convert value of type 'NSMutableDictionary' to expected argument type 
'[String : AnyObject]’"

Do I need to iterate through the NSMutableDictionary and create a Swift 
Dictionary from it?

Maybe I’ve missed an easier way of doing this. All I want to happen is to be 
notified when the print operation is completed.

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: didPrint selector not called

2016-12-16 Thread Jeremy Hughes
>> OK - I misunderstood what Quincey was saying.
>> 
>> The passed-in delegate and selector are nil, but I obviously can’t be sure 
>> that they will always be nil.
>> 
>> All I’m actually trying to do is to clean up some objects that need to exist 
>> during the print operation. Is this the best way for me to be doing that?
> 
> I'm not an expert in this part of Cocoa.  Are there implicit system *callers* 
> of this method, or is it more of a system *utility* that you're expected to 
> call from your own code?  If it's the latter, then maybe instead of 
> overriding it you should just provide a different method that calls it, doing 
> whatever set up you need first and then passing in the appropriate delegate 
> and selector to do cleanup.

It’s just an application method, which overrides the method that the system 
calls from printDocument when a user chooses Print.

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: didPrint selector not called

2016-12-16 Thread Jeremy Hughes
Also, NSInvocation (used in the release notes sample code) is unavailable in 
Swift.

Jeremy

--

> On 16 Dec 2016, at 19:33, Jeremy Hughes  wrote:
> 
>> 
>> On 16 Dec 2016, at 19:29, John McCall  wrote:
>> 
>>> On Dec 16, 2016, at 11:24 AM, Jeremy Hughes  
>>> wrote:
>>> Thanks for the link.
>>> 
>>> I’ve looked at it, and I don’t think it applies in this case, because I’m 
>>> not actually overriding the document(_:didPrint:contextInfo:) method, just 
>>> providing it as a callback. There isn’t an override keyword before the 
>>> method, and there isn’t a superclass method that I can call through to. I 
>>> suppose it would apply if I had a subclass (of my document class) that 
>>> needed to override the callback. Does that seem right to you?
>> 
>> You're overriding printDocumentWithSettings to ignore the passed-in delegate 
>> and selector.  Unless you're certain that the passed-in delegate and 
>> selector are never useful, you're probably breaking something.
>> 
>> John.
> 
> OK - I misunderstood what Quincey was saying.
> 
> The passed-in delegate and selector are nil, but I obviously can’t be sure 
> that they will always be nil.
> 
> All I’m actually trying to do is to clean up some objects that need to exist 
> during the print operation. Is this the best way for me to be doing that?
> 
> 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/moon.rabbit%40virginmedia.com
> 
> This email sent to moon.rab...@virginmedia.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: didPrint selector not called

2016-12-16 Thread Jeremy Hughes

> On 16 Dec 2016, at 19:29, John McCall  wrote:
> 
>> On Dec 16, 2016, at 11:24 AM, Jeremy Hughes  
>> wrote:
>> Thanks for the link.
>> 
>> I’ve looked at it, and I don’t think it applies in this case, because I’m 
>> not actually overriding the document(_:didPrint:contextInfo:) method, just 
>> providing it as a callback. There isn’t an override keyword before the 
>> method, and there isn’t a superclass method that I can call through to. I 
>> suppose it would apply if I had a subclass (of my document class) that 
>> needed to override the callback. Does that seem right to you?
> 
> You're overriding printDocumentWithSettings to ignore the passed-in delegate 
> and selector.  Unless you're certain that the passed-in delegate and selector 
> are never useful, you're probably breaking something.
> 
> John.

OK - I misunderstood what Quincey was saying.

The passed-in delegate and selector are nil, but I obviously can’t be sure that 
they will always be nil.

All I’m actually trying to do is to clean up some objects that need to exist 
during the print operation. Is this the best way for me to be doing that?

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: didPrint selector not called

2016-12-16 Thread Jeremy Hughes
Thanks for the link.

I’ve looked at it, and I don’t think it applies in this case, because I’m not 
actually overriding the document(_:didPrint:contextInfo:) method, just 
providing it as a callback. There isn’t an override keyword before the method, 
and there isn’t a superclass method that I can call through to. I suppose it 
would apply if I had a subclass (of my document class) that needed to override 
the callback. Does that seem right to you?

Jeremy

--

> On 16 Dec 2016, at 18:26, Quincey Morris 
>  wrote:
> 
> On Dec 16, 2016, at 08:45 , Jeremy Hughes  wrote:
>> 
>> override func printDocumentWithSettings(printSettings: [String : AnyObject], 
>> showPrintPanel: Bool, delegate: AnyObject?, didPrintSelector: Selector, 
>> contextInfo: UnsafeMutablePointer)
>> {
>>  let didPrint = #selector(Document.document(_:didPrint:contextInfo:))
>>  
>>  super.printDocumentWithSettings(printSettings, showPrintPanel: 
>> showPrintPanel, delegate: delegate, didPrintSelector: didPrint, contextInfo: 
>> contextInfo)
>> }
> 
> Apart from the bug John described, where the selector is incorrectly for a 
> class method…
> 
> It’s not absolutely clear, but I think this method comes under the aegis of 
> “Advice for Overriders of Methods that Follow the 
> delegate:didSomethingSelector:contextInfo: Pattern” in the OS X release notes 
> archive:
> 
>   
> developer.apple.com/library/content/releasenotes/AppKit/RN-AppKitOlderNotes/
> 
> (Do a text search within the page to find the heading.)
> 
> This’ll make your head hurt, but the essence of it is that you’re not allowed 
> to throw away the selector that’s passed in to the method, and that’s exactly 
> what you’re doing.
> 
> Instead, you need to arrange for your “didPrint” method to invoke the 
> originally passed-in selector, and depending on the order in which things 
> need to happen, you make have to construct an invocation. I think (but I’m 
> not certain) that yours is the “easy” case where you don’t need to construct 
> the invocation, but you’re going to have to figure that out.
> 


___

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

Fwd: didPrint selector not called

2016-12-16 Thread Jeremy Hughes
Sorry - I forgot to copy to the list.

Jeremy

--

> Begin forwarded message:
> 
> From: Jeremy Hughes 
> Subject: Re: didPrint selector not called
> Date: 16 December 2016 at 19:15:10 GMT
> To: John McCall 
> 
>> On 16 Dec 2016, at 17:24, John McCall  wrote:
>> 
>>> On Dec 16, 2016, at 8:45 AM, Jeremy Hughes  
>>> wrote:
>>> Hi,
>>> 
>>> I’m overriding printDocumentWithSettings in order to get a notification for 
>>> when printing has finished, but the didPrint selector is never called.
>>> 
>>> This is the code:
>>> 
>>> class func document(document: NSDocument, didPrint: Bool, contextInfo: 
>>> UnsafeMutablePointer)
>>> {
>>> print("document was printed”)
>>> }
>>> 
>>> override func printDocumentWithSettings(printSettings: [String : 
>>> AnyObject], showPrintPanel: Bool, delegate: AnyObject?, didPrintSelector: 
>>> Selector, contextInfo: UnsafeMutablePointer)
>>> {
>>> let didPrint = #selector(Document.document(_:didPrint:contextInfo:))
>>> 
>>> super.printDocumentWithSettings(printSettings, showPrintPanel: 
>>> showPrintPanel, delegate: delegate, didPrintSelector: didPrint, 
>>> contextInfo: contextInfo)
>>> }
>>> 
>>> Does anyone know why this doesn’t work?
>> 
>> The selector is invoked on the delegate object that you pass.  Since the 
>> selector is for a class method on Document, the delegate needs to be the 
>> class object for Document, which I assume it probably isn't.
>> 
>> It does seem kindof weird to be ignoring the delegate/selector pair that was 
>> passed in, though.
>> 
>> John.
> 
> Thanks!
> 
> I’ve changed the method to an instance method and passed in self as the 
> delegate - it works fine now.
> 
> 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

didPrint selector not called

2016-12-16 Thread Jeremy Hughes
Hi,

I’m overriding printDocumentWithSettings in order to get a notification for 
when printing has finished, but the didPrint selector is never called.

This is the code:

class func document(document: NSDocument, didPrint: Bool, contextInfo: 
UnsafeMutablePointer)
{
print("document was printed”)
}

override func printDocumentWithSettings(printSettings: [String : AnyObject], 
showPrintPanel: Bool, delegate: AnyObject?, didPrintSelector: Selector, 
contextInfo: UnsafeMutablePointer)
{
let didPrint = #selector(Document.document(_:didPrint:contextInfo:))

super.printDocumentWithSettings(printSettings, showPrintPanel: 
showPrintPanel, delegate: delegate, didPrintSelector: didPrint, contextInfo: 
contextInfo)
}

Does anyone know why this doesn’t work?

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: Dismissing Open dlog before doc actually opens

2013-08-14 Thread Jeremy Hughes
Graham Cox (14/8/13, 06:51) said:

>They did, which is why first modeless dialogs (from System 1? 2?) and
>then sheets (OSX 1.0) were developed. Even as far back as the original
>Inside Macintosh the use of modal dialogs was strongly discouraged when
>it was possible to use something else. The original system design used a
>modal Open dialog but this became a modeless dialog in System 7 (1991),
>if I recall correctly.

I must be missing something here.

Which Apple applications have non-modal Open dialogs?

All the ones that I tried (TextEdit, Preview.app, Safari, Xcode 3.2.6) have 
modal Open dialogs - you can't do anything in other documents while the Open 
dialog is displayed.

I'm running Snow Leopard, so maybe things are different in Mountain Lion - but 
Snow Leopard is a long way from System 7.

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: Overwhelming Options

2011-09-02 Thread Jeremy Hughes
Quincey Morris (1/9/11, 21:42) said:

>If it should happen that there was a practical need to change the column
>display frequently (dozens of times per day), choosing individual
>columns from a context menu would get very old very fast. In that case,
>the only practical choice might be an array of 39 checkboxes.

... which is what you get if you choose View Options from the iTunes View menu.

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

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


Re: devil of a time with an NSImageView

2009-08-21 Thread Jeremy Hughes
Quincey Morris (20/8/09, 19:31) said:

>On Aug 20, 2009, at 11:02, I. Savant wrote:
>
>>  I missed that thread. Do you happen to know some keywords from the
>> subject?
>
>No, I've looked for it but I can't find it. It was one of a number of
>similar questions around that time, possibly about iPhone views, and
>the comment was an afterthought to some other response, with no
>additional details. All I can remember is that it sent me scurrying to
>change some window controller awakeFromNib's to windowDidLoad's.

How about...

From Kevin Cathey (10/6/09, 06:37):

"We encourage you to use the controller's controller specific methods
for knowing when you content is loaded:

NSWindowController -- windowDidLoad
UIViewController -- viewDidLoad

Since the behavior of awakeFromNib differs between iPhone OS and Mac
OS X, using windowDidLoad or viewDidLoad will ensure you only receive
that message once: when the window or view is loaded."

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

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