Re: Need for Swift
> 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
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
> 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
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
> 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
> 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
> 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
> 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
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
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)
> 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)
> 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)
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
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
> 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
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
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
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
> 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
> 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
> 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
> 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
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
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
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
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?
> 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?
> 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?
> 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?
> 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?
> 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?
> 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?
> 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?
> 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?
> 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?
> 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?
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?
> 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?
> 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?
> 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?
> 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?
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
> 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, "validateEditing()” 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
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
> 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
> 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
> 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
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
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
> 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
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
> 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
> 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
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
> 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
> 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
> 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
> 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
> 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
>> 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
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
> 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
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
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
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
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
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
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