Lazy calculation of tooltip text
I have a UI item (text field) that displays a tooltip when the user hovers over it. However, the information to be displayed in the tooltip is dynamic and relatively expensive to compute. At the moment the tooltip is bound to a string property which I manually update twice a second. It seems that the right way to handle all this would be to compute the information only when I know the tooltip is about to display. However, googling and searching of headers has not led me to a way to do this. It seems that NSTextView has a method textView:willDisplayToolTip:forCharacterAtIndex: which would seem to offer the functionality I want. However, I can’t find anything equivalent for other view types. Any suggestions on how I might supply tooltip text dynamically, when the tooltip is about to display? [University of Glasgow: The Times Scottish University of the Year 2018] ___ 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: Property in class mirrored to user defaults
Thankyou Charles and Keary for your replies. I somehow hadn't thought of using NSDefaults as backing for the properties. There are a lot of properties involved, but with a macro or something I should be able to set it up without a massive code bloat. Will give that a go. Cheers Jonny On 12 Jun 2017, at 16:01, Charles Srstka <cocoa...@charlessoft.com> wrote: >> On Jun 12, 2017, at 4:04 AM, Jonathan Taylor <jonathan.tay...@glasgow.ac.uk> >> wrote: >> >> Hi all, >> >> This feels like a very basic question, but one that I have not had any luck >> searching for (maybe I am using the wrong terms?). >> >> At the moment I have properties in a (singleton) class that are bound to UI >> elements. At the moment they have the same automatic values every time the >> app is launched, although the user can change them while it is running. What >> I would like is for the user's previous choice to be remembered when the app >> is next launched. Obviously this would seem to be a job for NSUserDefaults. >> I am not sure quite what the right way to structure things is, though. >> >> All the simple examples I have seen bind to NSUserDefaults and then if the >> program actually wants to know what the value is, it simply accesses the >> values directly on NSUserDefaults. I would prefer not to do that, though >> (see below). >> >> What I ~think~ I would like is to still be able to access the values as >> properties of my class. That seems to me like the natural way, and it would >> seem odd to have two categories of value, some accessed through properties >> on the class, and some accessed some other way via NSUserDefaults. However, >> if I bind the UI elements to the shared user defaults object, is that not >> what will happen? Or is there some way that I can "link" my class and the >> user defaults object, so that the properties are saved in user defaults but >> I can still access them in a fairly seamless way from my class? I do like >> the idea of having the properties (and their types) explicitly declared as >> part of my class, rather than being mysterious objects that only exist in >> the user defaults. >> >> Does anyone have any advice on how I can achieve this, or on how I should be >> thinking about all this differently? >> Thanks >> Jonny > > If performance isn’t an issue, as it usually isn’t for properties linked to > UI elements, and you don’t want to bind the UI elements directly to an > NSUserDefaultsController, you can just use UserDefaults as the backing for a > property, like this: > > class MyClass: NSObject { > // this is a property only so we can make key paths that will go > through it > @objc private let userDefaults: UserDefaults > private static let fooDefaultsKey = "Foo" > > @objc private static let keyPathsForValuesAffectingFoo: Set = > ["\(#keyPath(userDefaults)).\(MyClass.fooDefaultsKey)"] > @objc dynamic var foo: String { > get { return UserDefaults.standard.string(forKey: > MyClass.fooDefaultsKey) ?? "" } > set { UserDefaults.standard.set(newValue, forKey: > MyClass.fooDefaultsKey) } > } > > override init() { > self.userDefaults = UserDefaults.standard > > super.init() > } > } > > This is pretty cool; on recent releases of macOS, it’ll respond to changes in > the defaults even if they come from outside the process. So, if you observe > the “foo” property, and then manually use /usr/bin/defaults to change the > defaults, your notifications in the app will fire. > > Alternately, you can just set up the property at init time and then update > the defaults whenever it changes, like this. You won’t get the cool > observation behavior, though, unless you use KVO’s infamously ugly > observation APIs (the slick new closure-based one won’t work here, since > we’re stuck with using string keys for this). > > class MyClass: NSObject { > private static let fooDefaultsKey = "Foo" > > @objc dynamic var foo: String { > didSet { UserDefaults.standard.set(self.foo, forKey: > MyClass.fooDefaultsKey) } > } > > override init() { > self.foo = UserDefaults.standard.string(forKey: > MyClass.fooDefaultsKey) ?? "" > > super.init() > } > } > > Charles > ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Property in class mirrored to user defaults
Hi all, This feels like a very basic question, but one that I have not had any luck searching for (maybe I am using the wrong terms?). At the moment I have properties in a (singleton) class that are bound to UI elements. At the moment they have the same automatic values every time the app is launched, although the user can change them while it is running. What I would like is for the user's previous choice to be remembered when the app is next launched. Obviously this would seem to be a job for NSUserDefaults. I am not sure quite what the right way to structure things is, though. All the simple examples I have seen bind to NSUserDefaults and then if the program actually wants to know what the value is, it simply accesses the values directly on NSUserDefaults. I would prefer not to do that, though (see below). What I ~think~ I would like is to still be able to access the values as properties of my class. That seems to me like the natural way, and it would seem odd to have two categories of value, some accessed through properties on the class, and some accessed some other way via NSUserDefaults. However, if I bind the UI elements to the shared user defaults object, is that not what will happen? Or is there some way that I can "link" my class and the user defaults object, so that the properties are saved in user defaults but I can still access them in a fairly seamless way from my class? I do like the idea of having the properties (and their types) explicitly declared as part of my class, rather than being mysterious objects that only exist in the user defaults. Does anyone have any advice on how I can achieve this, or on how I should be thinking about all this differently? Thanks Jonny ___ 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: Relative URLs, and string encodings
>> My attempt like: >> [NSURL URLWithString:[path >> stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding] >> relativeToURL:relativeTo]; > > Ah, you want NSUTF8StringEncoding instead. Generally speaking, URL encoding > always uses UTF-8 nowadays. Thankyou for your reply Jens. That's reassuring. (And soon after sending that I discovered that my proposed use of NSUnicodeStringEncoding was badly broken because it prevented url.path.UTF8String from working. Surprise, surprise: using your recommended UTF8 makes that work! > You mean an open or close (aka “curly”) quote? They’re easily typed with > Option-[ and Option-Shift-[. Ah yes, I knew that once, back in the day before text editors started auto-creating the open/close quotes themselves. I only write them manually in LaTeX these days. Cheers Jonny ___ 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
Relative URLs, and string encodings
Can anyone help me with the seemingly simple task of creating a relative NSURL for a filesystem object? The catch here (sorry!) is that I really do need backward compatibility to 10.7, which rules out fileURLWithFileSystemRepresentation:isDirectory:relativeToURL: (which I suspect is the “right” way of doing this). My attempt like: [NSURL URLWithString:[path stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding] relativeToURL:relativeTo]; This had been working ok for some time, but I have just found it to be broken for filenames containing unusual characters. In particular, it fails when given a filename containing a “smart quote” (not easily created directly with the keyboard, but auto-generated as part of a time machine backup, based on the machine name). Although I do not recall why I used stringByAddingPercentEscapesUsingEncoding, I think it must have been because it failed on some other filename pattern if I did not do that. String encodings is something I know basically nothing about, I am afraid. I am speculating that what is happening is that the fancy apostrophe is not ASCII and so my code does not work for that filename. I can change the encoding to NSUnicodeStringEncoding, and things seem ok, but I don’t know whether that will now definitely work for all filenames, or whether I have just stored up an even more obscure problem for the future. So, finally getting to two actual questions: 1. Will unicode encoding give me a robust solution here? 2. Is there a differnet, better way (pre-10.9) I should be using to create a relative URL? Thanks for any advice Jonny. ___ 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: Prioritizing drawing of the important stuff
Hi everyone, Thankyou all for your replies. Plenty of food for thought there - much appreciated. Looks like timers and flow control is the way forward then, if I want to tackle this. I just thought I'd see if there was anything built in to the standard UI frameworks that might be able to help, but it seems not. To answer one of Quincey's comments: >> The low priority thing only really runs when *nothing* else at all is >> happening. > > This shouldn’t be happening, on most Macs. An average desktop Mac has at > least 2 CPU cores (4 logical CPUs), which should allow at least 2 > compute-bound tasks to proceed simultaneously... The reason for this is that the coalescing, post-when-idle NSNotifications I was talking about were being posted to the main queue. Hence all the main queue time was being taken up in ultra-smooth drawing of sliders etc, since that of course also happens on the main queue (UI drawing...). I agree that it looks as if I should bite the bullet and run all this stuff multithreaded. The thing is, a lot of it doesn't fundamentally ~need~ to run multithreaded - one thread should be enough to get drawing responsiveness that I'm pretty happy with, if I could just find a way to control what priorities the different aspects are being treated with. Sounds like timers, flow control and/or multiple threads/queues is the way to go if I want to solve this properly. Cheers Jonny. ___ 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: Prioritizing drawing of the important stuff
The point, though, is that the slider will happily update pretty much as as often as the CPU allows. The issue is how to control what the OS considers to be "smooth enough" slider updates - there's a point at which I'd much rather have it "only" update the slider and the quick-to-draw image 10 times/sec, and have a bit of time spare to do the low-priority drawing, rather than updating the slider and easy image 60 times/sec. On 29 Oct 2016, at 12:27, Slipp Douglas Thompson <apple+cocoa-...@slippyd.com> wrote: > You could just set up a simple debounce timer— reset it back to 0sec elapsed > time whenever the slider is updated, and if it reaches a small delay then the > HQ image is rendered (and remains on-screen until the slider is later moved > and the process repeats). No need to rely on GCD or threading. > > — Slipp > >> On Oct 29, 2016, at 4:37 AM, Jonathan Taylor <jonathan.tay...@glasgow.ac.uk> >> wrote: >> >> Hi all, >> >> This is a bit of a general question, but hopefully people may have some >> suggestions. I've got some drawing code that synthesizes an image in a >> window, which will change in response to sliders (e.g. changing the camera >> perspective). My problem is how to make it so that the redrawing of the >> image is as responsive as possible as the slider moves. >> >> At the moment I just respond to KVO notifications from the slider by >> redrawing. This works fairly well. However, after further development work >> my program is now a bit more complicated. Effectively, I have two images, >> one of which is expensive to draw and one less so. What I would like is to >> have the quick-to-draw one update fairly often, and the more expensive one >> at lower priority. Does anyone have any suggestions about how to achieve >> this? >> >> Ideally, I would like the quick image to continue to update responsively as >> the slider moves. I am less bothered about how responsive the slow image is. >> One way I could do this is to treat it as low priority, either though a low >> priority GCD thread or through coalescing post-when-idle NSNotifications. My >> experiments so far, though, suggest that this is a rather binary thing. The >> low priority thing only really runs when *nothing* else at all is >> happening. This can lead to a scenario where (as far as I can tell via >> Instruments) the OS is spending every moment of idle time redrawing a moving >> slider at some outrageous frequency, making it look ultra-smooth, but not >> dedicating *any* time at all to doing my low-priority drawing. >> >> So, I think this basically boils down to a question of load balancing. Is >> there a good way to balance the time my code spends on different drawing >> activities, making sure all do happen to some extent, but some more often >> than others? Importantly (and most challengingly I think) this includes UI >> drawing activities that the OS undertakes on my behalf (which I have less >> control over). >> >> I fear there is no easy solution to this, but if anyone has any suggestions >> for things I should look at, that would be really helpful. >> >> Cheers >> Jonny. >> ___ >> >> 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/apple%2Bcocoa-dev%40slippyd.com >> >> This email sent to apple+cocoa-...@slippyd.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: Prioritizing drawing of the important stuff
Hi Jeff, Thanks for your reply. Unless I am misunderstanding you, though, I think we are talking about two slightly different things? It seems that what you are referring to is useful in the case where there is a "low quality" and "high quality" method for redrawing the *same* image. In that case, inLiveResize would be useful for knowing which of the two to use. In my case, though, I have two separate images. In fact, one is an xy cross section through a 3D dataset, and one is a 3D rendering (which clearly takes longer to compute). It makes sense for the xy cross section redraw to be more responsive, since it is cheaper to draw, but I don't want the 3D rendering to be neglected entirely. Is there a way that what you describe can help there, or are we talking about two slightly different things here? Cheers Jonny. On 29 Oct 2016, at 11:24, Jeff Szuhay <j...@szuhay.org> wrote: > Actually, there is. This sounds a lot like the resize logic built into the > framework. > > In Apple’s “View Programming Guide” there is a section dedicated to “Drawing > During Live Window Resizing” > You already have the fast and slow methods for drawing so you can use them if > you pay attention to > > -(BOOL) inLiveResize > > Also, you can override viewWillStartLiveResize: and viewDidEndLiveResize: > methods on your NSView. > > There is also a demo app that uses bindings to change the window shape and > transparency based on its size that might be helpful. > > So, I think I am saying this problem is not new and has been addressed in > several different ways in the NSView class. > > >> On Oct 29, 2016, at 2:37 AM, Jonathan Taylor <jonathan.tay...@glasgow.ac.uk> >> wrote: >> >> Hi all, >> >> This is a bit of a general question, but hopefully people may have some >> suggestions. I've got some drawing code that synthesizes an image in a >> window, which will change in response to sliders (e.g. changing the camera >> perspective). My problem is how to make it so that the redrawing of the >> image is as responsive as possible as the slider moves. >> >> At the moment I just respond to KVO notifications from the slider by >> redrawing. This works fairly well. However, after further development work >> my program is now a bit more complicated. Effectively, I have two images, >> one of which is expensive to draw and one less so. What I would like is to >> have the quick-to-draw one update fairly often, and the more expensive one >> at lower priority. Does anyone have any suggestions about how to achieve >> this? >> >> Ideally, I would like the quick image to continue to update responsively as >> the slider moves. I am less bothered about how responsive the slow image is. >> One way I could do this is to treat it as low priority, either though a low >> priority GCD thread or through coalescing post-when-idle NSNotifications. My >> experiments so far, though, suggest that this is a rather binary thing. The >> low priority thing only really runs when *nothing* else at all is >> happening. This can lead to a scenario where (as far as I can tell via >> Instruments) the OS is spending every moment of idle time redrawing a moving >> slider at some outrageous frequency, making it look ultra-smooth, but not >> dedicating *any* time at all to doing my low-priority drawing. >> >> So, I think this basically boils down to a question of load balancing. Is >> there a good way to balance the time my code spends on different drawing >> activities, making sure all do happen to some extent, but some more often >> than others? Importantly (and most challengingly I think) this includes UI >> drawing activities that the OS undertakes on my behalf (which I have less >> control over). >> >> I fear there is no easy solution to this, but if anyone has any suggestions >> for things I should look at, that would be really helpful. >> >> Cheers >> Jonny. >> ___ >> >> 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/jeff%40szuhay.org >> >> This email sent to j...@szuhay.org > ___ 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
Prioritizing drawing of the important stuff
Hi all, This is a bit of a general question, but hopefully people may have some suggestions. I've got some drawing code that synthesizes an image in a window, which will change in response to sliders (e.g. changing the camera perspective). My problem is how to make it so that the redrawing of the image is as responsive as possible as the slider moves. At the moment I just respond to KVO notifications from the slider by redrawing. This works fairly well. However, after further development work my program is now a bit more complicated. Effectively, I have two images, one of which is expensive to draw and one less so. What I would like is to have the quick-to-draw one update fairly often, and the more expensive one at lower priority. Does anyone have any suggestions about how to achieve this? Ideally, I would like the quick image to continue to update responsively as the slider moves. I am less bothered about how responsive the slow image is. One way I could do this is to treat it as low priority, either though a low priority GCD thread or through coalescing post-when-idle NSNotifications. My experiments so far, though, suggest that this is a rather binary thing. The low priority thing only really runs when *nothing* else at all is happening. This can lead to a scenario where (as far as I can tell via Instruments) the OS is spending every moment of idle time redrawing a moving slider at some outrageous frequency, making it look ultra-smooth, but not dedicating *any* time at all to doing my low-priority drawing. So, I think this basically boils down to a question of load balancing. Is there a good way to balance the time my code spends on different drawing activities, making sure all do happen to some extent, but some more often than others? Importantly (and most challengingly I think) this includes UI drawing activities that the OS undertakes on my behalf (which I have less control over). I fear there is no easy solution to this, but if anyone has any suggestions for things I should look at, that would be really helpful. Cheers Jonny. ___ 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: Mixed-state checkboxes
Thanks Quincey, that makes sense what you're saying about it being more an action method, and your suggested approach sounds nice. However, I have not managed to quite get things working based on what I think you were describing. I have set up an action on the checkbox, and based on your comment about "With no setter, the binding won’t try to update the property, it’ll basically be read-only" I changed the bound property to read-only. Maybe that was not what you had intended, but with Xcode 5 at least there did not seem to be a way I could explicitly say that the binding should only be used for reading only. Anyway, if I do that, I get an error: "this class is not key value coding-compliant for the key globalChannelEnableState". I wonder if I have misunderstood what you were meaning? Also, when you write: > You don’t need to dispatch anything to a later iteration of the main event > loop. (Even in your current code — the setter will automatically generate the > KVO notification, so doing it again later is redundant.) which of the three choices of code (switched by #if statements...) are you referring to, from the code I originally posted? For me, in the first and third options the will/didChangeValue calls are essential to avoid the checkbox being left displaying '-' state. Is that not the behaviour you would expect here? One option would be to take up your suggestion of the action method, but abandon the binding altogether and just set the actual state of the UI element directly from my code. I'd definitely be interested in understanding what it sounded like you were suggesting with a "basically read-only" binding though... Cheers Jonny On 8 Jul 2016, at 18:35, Quincey Morris <quinceymor...@rivergatesoftware.com> wrote: > On Jul 8, 2016, at 05:36 , Jonathan Taylor <jonathan.tay...@glasgow.ac.uk> > wrote: >> >> My setter code currently looks like this: >> >> -(void)setGlobalChannelEnableState:(NSInteger)state > > In the circumstances you describe, a setter method is effectively an action > method, not a setter — that is, it becomes a method that’s called when your > code needs to do something, rather than a way to set some state. As you’ve > found, the real setter method tends to work against you here, because you > have to figure out what the binding expects with the changed value it thinks > it’s setting. > > So, I think a cleaner approach is to leave out the setter method entirely, > and use a real action method instead. With no setter, the binding won’t try > to update the property, it’ll basically be read-only. When the checkbox is > clicked, the action method is still invoked — it’s a NSButton, after all. All > the action method has to do is retrieve the current global state via the > getter, then set the individual states needed to flip it, sandwiched between > one pair of will/didChange calls for the key “globalChannelEnableState”. > > You don’t need to dispatch anything to a later iteration of the main event > loop. (Even in your current code — the setter will automatically generate the > KVO notification, so doing it again later is redundant.) > ___ 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
Mixed-state checkboxes
Hi all, I'm trying to work out the correct way to handle a mixed-state checkbox (NSButton checkbox with allowsMixedState=YES), bound to a property on my controller. I am intending it to serve as an "applies to all" type control at the head of a column of checkboxes - so if other checkboxes in the column are toggled, it will display a state of on (if all in column are on), off (if all are off), or mixed if there is a mixture of states in the column. My property has no backing variable, but a manually-implemented getter and setter. I am happy with how the getter is working - it scans the column and returns the appropriate state. What I am not sure about is how to handle the setter. It seems that allowsMixedState makes it possible to *present* the mixed state, but also means that the user can click through the three states in order. What I believe the normal interface would be in my situation is for a user click on a box in on (or off) state to switch it to off (or on), and a click on mixed state puts it to either on or off (not sure which). What I would not expect is for a click when in off state to put it into MIXED state. In this interface (if I have described it clearly!) it makes no sense for the user to actively put the checkbox into mixed state. So... my question is how to implement the correct behaviour? 1. It would be great if there was a flag I could set that says "behave like I want", but I can't see one! 2. Failing that, I believe what I need to do is to spot the setter being called with a value of -1 (mixed), and overrule that. However, I haven't found a way of doing that that "feels right" - all successful approaches feel like a hack rather than the right way of doing it. My setter code currently looks like this: -(void)setGlobalChannelEnableState:(NSInteger)state { if (state == -1) { #if 0 // Checkbox remains in '-' state if I use this code [self willChangeValueForKey:@"globalChannelEnableState"]; state = 1; [self didChangeValueForKey:@"globalChannelEnableState"]; #elif 1 // Works. Schedule another call in a moment, to update the value to 'on' dispatch_async(dispatch_get_main_queue(), ^{ self.globalChannelEnableState = 1; }); return; #else // Also works. Change the input state and fall through to the code that does the actual updating (below) state = 1; dispatch_async(dispatch_get_main_queue(), ^{ [self willChangeValueForKey:@"globalChannelEnableState"]; [self didChangeValueForKey:@"globalChannelEnableState"]; }); #endif } // Update state for all individual channels [code not shown here] } Can anybody comment, and maybe suggest a more elegant way of handling this? For brevity, I have not shown the getter code, but remember that there is no backing variable and the getter just examines the current program state to determine what the correct value is. Thanks for any comments Jonny. ___ 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: Prioritize my own app's disk access
On 6 Jul 2016, at 18:01, Quincey Morris <quinceymor...@rivergatesoftware.com> wrote: > On Jul 6, 2016, at 03:06 , Jonathan Taylor <jonathan.tay...@glasgow.ac.uk> > wrote: >> >> a single lost frame will be fairly catastrophic for the scientific experiment > > If this is genuinely your scenario, then nothing mentioned in this thread is > going to satisfy your requirements. It is pure whimsy to expect any > prioritization mechanic to ensure that the capture is buffered around random > unrelated user interactions with the Mac. All fair points, but the fact is that in practice it works remarkably well at the moment. There is still some spare i/o and cpu capacity, and in practice the 8GB of ram *does* act as a very effective, and very large, buffer. There is a clear indication displayed if a backlog starts building, and even a backlog of 1000 frames is easily recoverable without loss. A colleague had tried to transfer some old data to another machine for analysis during an experiment, and it became clear this was causing a backlog to build in the live recording. It was no problem just to cancel the Finder copy operation, and the live recording recovered and cleared the backlog. My question was just intended to explore whether there was something easy I could do to make that sort of low-priority background request more likely to work without causing conflicts. It sounds like the answer is probably not! (Though I have definitely learned some very useful stuff in the process) ___ 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: Prioritize my own app's disk access
Thanks for your reply Alastair. Definitely interested in thinking about your suggestions - some responses below that will hopefully help clarify: > The first thing to state is that you *can’t* write code of this type with the > attitude that “dropping frames is not an option”. Fundamentally, the problem > you have is that if you generate video data faster than it can be saved to > disk, there is only so much video data you can buffer up before you start > swapping, and if you swap you will be dead in the water --- it will kill > performance to the extent that you will not be able to save data as quickly > as you could before and the result will be catastrophic, with far more frames > dropped than if you simply accepted that there was the possibility the > machine you were on was not fast enough and would have to occasionally drop a > frame. I should clarify exactly what I mean here. Under normal circumstances I know from measurements that the i/o can keep up with the maximum rate at which frames can be coming in. I very rarely see any backlog at all reported, but might occasionally see a transient glitch (if CPU load momentarily spikes) of the order of 10MB backlog that is soon cleared. With that as the status quo, and 8GB of RAM available, something has gone badly, badly wrong if we enter vm swap chaos. When I say "dropping frames is not an option", what I mean is that a single lost frame will be fairly catastrophic for the scientific experiment, and so my priorities in order are: (1) ensure the machine specs leave plenty of headroom above my actual requirements, (2) try and do anything relatively simple I can do to ensure my code is efficient and marks threads/operations/etc as high or low priority where possible, (3) identify stuff that the user should avoid doing (which looks like it includes transferring data off the machine while a recording session is in progress - hence this email thread!), (4) not worry too much about what to do when we *have* already ended up with a catastrophic backlog (i.e. whether to drop frames or do something else), because at that point we have failed in the sense that the scientific experiment will basically need to be re-run. I should also clarify that (in spite of my other email thread running in parallel to this) I am not doing any complex encoding of the data being streamed to disk - these are just basic TIFF images and metadata. The encoding I referred to in my other thread is optional offline processing of previously-recorded data. > The right way to approach this type of real time encoding problem is as > follows: > > 1. Use statically allocated buffers (or dynamically allocated once at encoder > or program startup). DO NOT dynamically allocate buffers as you generate > data. > > 2. Knowing the rate at which you generate video data, decide on the maximum > write latency you need to be able to tolerate. This (plus a bit as you need > some free to encode into) will tell you the total size of buffer(s) you need. OK. > 3. *Either* > > (i) Allocate a ring buffer of the size required, then interleave encoding > and issuing I/O requests. You should keep track of where the > as-yet-unwritten data starts in your buffer, so you know when your encoder is > about to hit that point. Or > > (ii) Allocate a ring *of* fixed size buffers totalling the size required; > start encoding into the first one, then when finished, issue an I/O request > for that buffer and continue encoding into the next one. You should keep > track of which buffers are in use, so you can detect when you run out. > > 4. When issuing I/O requests, DO NOT use blocking I/O from the encoder > thread. You want to be able to continue to fetch video from your camera and > generate data *while* I/O takes place. GCD is a good option here, or you > could use a separate I/O thread with a semaphore, or any other asynchronous > I/O mechanism (e.g. POSIX air, libuv and so on). > > 5. If you find yourself running out of buffers, drop frames until buffer > space is available, and display the number of frame drops to the user. This > is *much* better than attempting to use dynamic buffers and then ending up > swapping, which is I think what’s happening to you (having read your later > e-mails). I am making good use of GCD here (and like it very much!). There are quite a few queues involved, and one is a dedicated disk-writing queue. The main CPU-intensive work going on in parallel with this is some realtime image analysis, but this is running on a concurrent queue. Hopefully my detail above explains why I really do not want to drop frames and/or use a ring buffer. Effectively I have a buffer pool, but if I exhaust the buffer pool then (a) something is going badly wrong, and (b) I prefer to expand the buffer pool as a last-ditch attempt to cope with the backlog rather than terminating the experiment right then and there. > Without knowing
Re: Prioritize my own app's disk access
Thanks everyone for your replies on this second question of mine. Some responses below: On 5 Jul 2016, at 18:20, Quincey Morriswrote: > What worries me about the Darwin-level (i.e. Unix-level) API suggestions that > others have made is that you don’t know how these interact with Cocoa apps. > You didn’t actually say whether your app is a Cocoa app, but if so … It is indeed a cocoa app. > I think the best modern approach is to route your CPU and IO usage via GCD. > That is, from the point where some callback gives you raw video, use > dispatch_async to schedule the processing on a GCD queue, and use the GCD I/O > primitives to actually do the I/O. > That will allow you to specify a quality of service (“user interactive” is > the highest), which should interact properly with other apps, e.g. the Finder > doing a large copy. > That should take care of CPU and IO. For memory, I agree with Jens that you > should preallocate and reuse memory buffers, rather than re-allocating them, > as far as possible. Interesting. I know and love GCD queues, but have not played with the I/O stuff. As far as the quality of service goes, I can't see the APIs for that (looking in the 10.9 SDK, at least). Am I looking in the wrong place? Text search for variants on "user interactive" haven't brought up anything for me in the "dispatch" folder. If I am honest, I suspect I will probably leave things as-is - the for the same pragmatic reasons I mentioned in my other email. Unless and until I have problems with i/o throughput when my own app is running unmolested, I think I'll probably just reiterate advice to users not to leave large copy operations running in the background while also recording to disk! I thought I would ask the question just in case there was an easy solution I should know about, but it sounds as if (understandably) any solution would be fairly involved and require some structural changes to my code. That's not to say that it isn't very interesting to broaden my mind and understand better what APIs are out there, for the next time... On 5 Jul 2016, at 17:19, Jens Alfke wrote: > In addition to increasing I/O priority, there may be other ways to make your > disk writes more efficient. For example you can preallocate space for the > file before writing to it. Writing in larger chunks may also help. (Of course > you may have tried these already.) I confess that currently I am using pure cocoa -writeToFile:atomically calls. I am fully aware that this is very unlikely to be the best way to do high performance IO, but it's great in terms of convenience. Again, I'm afraid (in the very specific context of a not-that-widely-distributed program running on dedicated computers) my question was fishing for a low-hanging fruit that might allow me a quick fix that left my own code as-is but encouraged the Finder to play nicely along with my not-entirely-optimal code :-) > Using wired memory for your buffers is also a good idea, since if any of > those buffers get paged out things will really go to hell. Buffer paging is indeed what eventually brings the program (and machine) to its knees if things go *really* badly wrong in terms of a backlog. I'm not seeing how this would solve a fundamental problem of i/o bandwidth being inadequate, but I can see that this would be a good thing to do in terms of preventing some *transient* condition from tipping things from one stable state (streaming to disk successfully) to another stable, but disastrous, state (thrashing the disk due to paging, meaning the frames can't be saved fast enough, more backlog, more thrashing, etc). > Also, I assume you’ve profiled the code and are confident that it’s being > constrained by I/O bandwidth and not CPU time? (It’s possible that I/O > requests made by real-time threads get higher priority; I can’t remember if > this is the case, as it’s a long time since I’ve had to deal with this sort > of stuff.) Yes. Definitely measured as an i/o bandwidth issue in this case. I am presuming (though have not profiled on this level of detail) that the problem is primarily one of seek times on a magnetic disk - a Finder copy going on in the background is competing with my own writes in terms of where the disk head needs to be... ___ 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: Property synthesis trouble - 32 vs 64 bit builds
On 5 Jul 2016, at 22:22, "Gary L. Wade"wrote: > You might need to write some lower level stuff, but some of the things in > there can be done, albeit differently. Apple knows I've submitted a number of > bugs and incident reports to get codecs supported in later frameworks. Do the > same. It may happen. ... ah, and I've just seen this reply from Gary as well. That's good to know - maybe I should take a fresh look if I do commit to the switch to a 64-bit build. ___ 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: Property synthesis trouble - 32 vs 64 bit builds
>> Quicktime. > > Oh, you poor thing. That’s one nasty API. (Actually dozens of nasty APIs.) O_o Yep. I rely on code that I worked out years ago, with the help of examples on the internet, and I do my best to leave that code untouched! >> My code has been 32-bit only since I first wrote it, because I make use of >> the APIs in QuickTime/ImageCompression.h for encoding movies. It's my >> understanding (as of last time I checked) that no equivalent functionality >> is available in the newer APIs. > > AVFoundation is supposed to be the replacement for QuickTime, and definitely > supports video encoding. I’ve only used it for audio, though, so I don’t know > the details of its video support. Unless it has been enhanced, I think the support for proper compression was lacking, and as a result any generated movie files would be enormous. ___ 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: Property synthesis trouble - 32 vs 64 bit builds
Thanks everyone for your replies - some responses below: On 5 Jul 2016, at 20:55, Greg Parkerwrote: > A synthesized property must use one of the following types of storage: > 1. An ivar in that class that @synthesize creates. > 2. An ivar in that class that you defined yourself. > > @synthesize on 32-bit macOS doesn't support #1. The problem is that 32-bit > macOS doesn't support non-fragile ivars. Allowing @synthesize to create ivars > would make it too easy to accidentally change ivar layout and break > compatibility. > > No platform allows @synthesize to bind to a superclass ivar. That would make > it too easy to accidentally bind to an unrelated superclass ivar when you > really wanted to create a new ivar. That last statement is a surprise to me. I had believed that the 32-bit code I posted was doing just that - MutableSettings binding its property to the ivar in ImmutableSettings. Certainly it's not clear to me how that statement *and* your statement that #1 is not supported on 32-bit could both be true (there is no backing ivar that I declare in the mutable subclass). I also ~think~ the code is working correctly on a 32-bit platform (and has been for several years). I'm not meaning to be argumentative, just trying to get my head around this :-) On 5 Jul 2016, at 18:12, Quincey Morris wrote: > I’d recommend a different approach, especially if there’s no behavior for the > property other than getting or setting an instance variable (which I assume, > because you’re trying to use synthesis): > [...] > It may sound weird to make the property (internally) settable in an immutable > class, but the instance variable is always modifiable in the superclass > anyway, so it’s kinda the same thing. Having a private setter there doesn’t > really change anything. Interesting. It does indeed sound weird, but I agree that it shouldn't actually be any different to what I'm currently doing. I might just give that a go! Does this approach have any specific advantages compared to the approach suggested by Keary (i.e. basically don't do any synthesis, and just write a getter in the base class and a setter in the subclass)? > Side note: > > Why are you even supporting 32-bit architectures on the Mac? The only good > reason I can think of is if you must still update users running OS X 10.5. > Users of 10.6.8 and above can (and should) use 64-bit versions of apps. Quicktime. My code has been 32-bit only since I first wrote it, because I make use of the APIs in QuickTime/ImageCompression.h for encoding movies. It's my understanding (as of last time I checked) that no equivalent functionality is available in the newer APIs. That, plus a big dose of "if it ain't broke, don't fix it", as a scientist for whom this Cocoa application of mine is a very helpful tool for me and my colleagues, but is just a means to an end rather than a product in its own right. I have only now started looking at 64 bit (knowing I am losing the quicktime functionality) because I wanted to look at interfacing with libraries that are 64-bit only. ___ 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: Property synthesis trouble - 32 vs 64 bit builds
Thanks for that information - that’s very helpful. It sounds from what you are saying as if there is nothing wrong with me redefining the *property* in the subclass (as read-write), but that it’s just the synthesis itself that is the problem? Assuming that is the case, I can easily(*) rectify that by writing explicit setters/getters, so I will do that. (*) there are rather a lot of these properties in the actual original code, but it just involves a lot of typing! On 5 Jul 2016, at 16:12, Keary Suska <cocoa-...@esoteritech.com> wrote: > >> On Jul 5, 2016, at 5:36 AM, Jonathan Taylor <jonathan.tay...@glasgow.ac.uk> >> wrote: >> >> I have a problem with property synthesis in my code, which I hope somebody >> can advise on. I find I have to write different property synthesis code for >> 32- or 64-bit builds in order to avoid compiler errors. >> >> A minimal demonstration of the problem can be found below - build as part of >> a fresh project on Xcode 5 or 6, with ARC disabled. It surprises me that I >> have to write different synthesis code for 32- or 64-bit builds - and this >> then makes me worry that I am doing something more fundamentally wrong. Can >> anyone comment (or explain)? >> >> [I appreciate that this code may be old-fashioned in style - I am not even >> sure what is or is not the recommended style these days. It seems to work >> though - and, importantly, as far as I can tell the synthesized property >> myFlag on MutableSettings *does* map to the same backing variable, even on a >> 64-bit build where I am not able to specify the backing variable in the >> synthesis statement] > > 32 vs 64 is likely coincidental, and probably has more to do with compiler > differences. I.e., at that time, there were additional compiler “features” > for 64 bit vs 32 bit. So my thought is that what you are doing is wrong in > both cases, but you are simply getting different compiler errors. > > The essential issue I believe is that you cannot re-synthesize in a subclass. > You will have to specify the setter explicitly. The issue in the second > (64-bit) case is that when you specify @synthesize with an instance variable > you are specifying a *new* instance variable on that class, but the compiler > correctly warns you that that instance variable has already been defined in > the superclass and therefore cannot also be defined in the subclass. The 32 > bit compiler seems to be letting you get away with this error, but it could > have horrible unintended consequences. ___ 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: Prioritize my own app's disk access
Thanks Alastair. Mark Allan’s email set me off reading things in that area, and I am indeed reading the man page for setiopolicy_np at this very moment! Certainly sounds like the API I am looking for although, as you say, it’s not clear where the “default” policy fits into the hierarchy. The man page states that [IOPOL_IMPORTANT] "is the default I/O policy for new threads”, and so if true then that would suggest that all a program can do is DOWNgrade its priority. However, the man page is evidently not entirely correct, based on the result you got, so who knows! I also wonder what priority the Finder would use for copying a folder. I might hope it would set itself to STANDARD or THROTTLE; if it does do that, then that would suggest that even this is not proving enough to prevent my code getting backlogged… On 5 Jul 2016, at 16:34, Alastair Houghton <alast...@alastairs-place.net> wrote: > On 5 Jul 2016, at 13:36, Jonathan Taylor <jonathan.tay...@glasgow.ac.uk> > wrote: >> >> This is a long shot, but I thought I would ask in case an API exists to do >> what I want. One of the roles of my code is to record video to disk as it is >> received from a camera. A magnetic hard disk can normally keep up with this, >> but if the user is also doing other things on the computer (e.g. long file >> copy in the Finder) then we are unable to keep up, and accumulate an >> ever-increasing backlog of frames waiting to be saved. This eventually leads >> to running out of memory, thrashing, and an unresponsive computer. Dropping >> frames is not an option. In this case, the computer is a dedicated >> workstation running my code, so it *is* correct for me to consider my code >> to be the number 1 priority on the computer. >> >> What I am wondering is whether there is some way I can communicate this >> requirement, to cause other apps such as the finder to get disk access at >> lower priority. Or alternatively, a way that I can demand high priority >> temporarily, at times when I identify that we have accumulated a save >> backlog? > > Take a look at get/setiopolicy_np(). It isn’t clear from the documentation > exactly what the default behaviour is; when I tried calling getiopolicy_np() > I got IOPOL_DEFAULT, which isn’t even mentioned as a value on the man page, > but you may find that setting your thread/process’s IO policy to > IOPOL_IMPORTANT solves your problem. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Prioritize my own app's disk access
This is a long shot, but I thought I would ask in case an API exists to do what I want. One of the roles of my code is to record video to disk as it is received from a camera. A magnetic hard disk can normally keep up with this, but if the user is also doing other things on the computer (e.g. long file copy in the Finder) then we are unable to keep up, and accumulate an ever-increasing backlog of frames waiting to be saved. This eventually leads to running out of memory, thrashing, and an unresponsive computer. Dropping frames is not an option. In this case, the computer is a dedicated workstation running my code, so it *is* correct for me to consider my code to be the number 1 priority on the computer. What I am wondering is whether there is some way I can communicate this requirement, to cause other apps such as the finder to get disk access at lower priority. Or alternatively, a way that I can demand high priority temporarily, at times when I identify that we have accumulated a save backlog? I can see reasons why this is probably not possible, but I thought I’d ask if anyone has any suggestions that might be relevant here. Thanks for any suggestions Jonny. ___ 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
Property synthesis trouble - 32 vs 64 bit builds
Hi all, I have a problem with property synthesis in my code, which I hope somebody can advise on. I find I have to write different property synthesis code for 32- or 64-bit builds in order to avoid compiler errors. A minimal demonstration of the problem can be found below - build as part of a fresh project on Xcode 5 or 6, with ARC disabled. It surprises me that I have to write different synthesis code for 32- or 64-bit builds - and this then makes me worry that I am doing something more fundamentally wrong. Can anyone comment (or explain)? [I appreciate that this code may be old-fashioned in style - I am not even sure what is or is not the recommended style these days. It seems to work though - and, importantly, as far as I can tell the synthesized property myFlag on MutableSettings *does* map to the same backing variable, even on a 64-bit build where I am not able to specify the backing variable in the synthesis statement] Cheers Jonny @interface ImmutableSettings : NSObject { BOOL_myFlag; } @property (readonly) BOOL myFlag; @end @interface MutableSettings : ImmutableSettings @property (readwrite) BOOL myFlag; @end @implementation ImmutableSettings -(id)init { if (!(self = [super init])) return nil; _myFlag = true; return self; } @synthesize myFlag = _myFlag; @end @implementation MutableSettings // This is very odd - I get errors on 64-bit builds if I specify a backing variable for synthesis, // but I get errors on 32-bit builds if I *don't* specify a backing variable!? #if defined(__x86_64__) // On 32-bit builds I get an error here: // "Synthesized property 'myFlag' must either be named the same as a compatible instance variable or must explicitly name an instance variable" @synthesize myFlag; #else // On 64-bit builds I get an error here: // "Property 'myFlag' attempting to use instance variable '_myFlag' declared in super class 'ImmutableSettings'" @synthesize myFlag = _myFlag; #endif @end ___ 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
Tick marks on scroll bars
Hi all, Does anyone know a way of implementing "tick marks" on a scroll bar, in the way that Xcode does to mark code lines where there is an error/warning? From reading header files, I can't see any obvious built-in API to implement this feature, but perhaps somebody knows of a custom class that somebody has written to implement this functionality? It's something I would like to use, and would do if it was comparatively simple to do so, but it's not crucial enough that it would be worth my time to write a custom subclass from scratch to do it I suspect (I have no experience of customizing controls, even if to an expert it might be comparatively simple!). Thanks for any suggestions... Jonny ___ 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: ARC [was Protecting against "app nap"]
Hi Jens, Thanks again for your reply. I'm sure this has been done to death over the years on the list, but... you would definitely recommend ARC then, would you? I've been a bit put off by what seems like regular questions on the list(s) about debugging and fixing edge cases where ARC doesn't work. I guess that only shows the times when it doesn't work, but it's rather left me thinking that it's just the same, but with less explicit indication of what is going on. Is that an unfair assessment, in your view? Best regards, Jonny. On 11 May 2016, at 16:10, Jens Alfke <j...@mooseyard.com> wrote: > >> On May 11, 2016, at 2:31 AM, Jonathan Taylor <jonathan.tay...@glasgow.ac.uk> >> wrote: >> >> I guess I just found method naming a bit odd (not really referring to an >> object at all), and might have expected it to have an ‘alloc/new’ naming >> since I’d have thought the API would be almost exclusively used for >> activities that continue beyond the calling scope. > > The only methods named +alloc or +new are the core methods on NSObject that > instantiate objects. (There’s also -copy and -mutableCopy.) Regular methods > don’t use that naming scheme nor return owned references, they just > consistently return unowned references. That keeps the rules simpler. > > (And I really recommend using ARC! It saves trouble and eliminates a lot of > bugs, like this one.) > > —Jens ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Protecting against "app nap"
Thankyou both for your replies - a couple of replies below: On 10 May 2016, at 23:33, Jens Alfkewrote: >> However, I was a bit surprised to find that I seem to need to explicitly >> retain the object I get back [this is non-ARC code…] if I want my request to >> remain in effect or even for the object to remain allocated to allow me to >> call endActivity at a later point. > > It’s standard Cocoa memory management: when an object is returned to you from > a method, you don’t own a reference to it, so it’s not guaranteed to remain > valid. Since you’re holding onto the object, in order to call -endActivity > later, you must be storing it in a non-local variable, so you need to retain > it. Fair enough. I agree that according to standard memory and naming conventions I should be expecting to have to retain the object. I guess I just found method naming a bit odd (not really referring to an object at all), and might have expected it to have an ‘alloc/new’ naming since I’d have thought the API would be almost exclusively used for activities that continue beyond the calling scope. Oh well. >> My question here is what is the most appropriate way of identifying in code >> whether this feature is available, to ensure I only set it when it will be >> accepted. > > Hm, it’s hard to say, because the declaration of DISPATCH_TIMER_STRICT > doesn’t specify what OS versions it’s usable with (via > __OSX_AVAILABLE_STARTING or something similar.) You may have to do some > research to narrow down when it was added. OK, will do. Just wasn’t sure if there was a better way to nail it down. On 10 May 2016, at 18:40, Paul Scott wrote: > Did you try clicking “Prevent app nap” in the “Info” inspector for the app? I’ll be honest, I hadn’t spotted that. Useful to know about (and it looks like setting NSAppSleepDisabled in Info.plist should achieve the same thing without manual user intervention). However, it looks like beginActivityWithOptions has a broader remit than just app nap, so I’ll go with the belt and braces approach and do both… Cheers Jonny ___ 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
Protecting against "app nap"
Hi all, I’m hoping somebody can help me work out how to protect my code against the effects of “app nap”. This code is driving a scientific experiment, unattended, and it is catastrophic when the OS decides that my timers running at 10Hz should only be fired every 10 seconds or so… which it turns out has been happening! I have been calling [[NSProcessInfo processInfo] beginActivityWithOptions:…] from -applicationDidFinishLaunching. I know that a blanket declaration like this would typically be considered poor practice, but honestly if the program is running then the experiment is running and I need the OS not to mess with my timings to that extent. Anyway, that seems to help stop the timer weirdness. However, I was a bit surprised to find that I seem to need to explicitly retain the object I get back [this is non-ARC code…] if I want my request to remain in effect or even for the object to remain allocated to allow me to call endActivity at a later point. I wasn’t expecting to have to retain it, and there’s no explicit mention of that in the headers, so I just wanted to check that is to be expected, or whether I may be doing something weirdly wrong. The other thing I wanted to ask relates to creating a timer using dispatch_source_create. I have tried to be flexible where I can in terms of providing a leeway for non-critical timers, but others I really want to have control over. For these I am specifying DISPATCH_TIMER_STRICT, also in the hope of dissuading the OS from trying to be too clever for its own good. I notice that using this flag leads to dispatch_source_create failing on 10.8.5, which I presume is because the flag is not recognised (or needed) on that OS version. My question here is what is the most appropriate way of identifying in code whether this feature is available, to ensure I only set it when it will be accepted. Any help much appreciated! Cheers Jonny. ___ 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: Identify image file count in directory
Hi Gary, Thanks for your reply. Do you know for sure that this should be significantly faster, or were you just guessing? You didn't say which particular API you had in mind, but some reading has led me to the fts APIs. These appear to be about 20% faster than NSFileManager (I specified FTS_NAMEONLY). Better than a kick in the teeth, but still seems to me like it might be possible to do it faster. I measured about 2.5 seconds for a directory on a "Mac OS Extended (Journaled)" external USB3 hard disk containing 110,000 files with names around 15 characters long. I don't know much about how filesystems are structured, so this information may not be all in one place, but that should represent less than 1MB/s of data read in order to get a list of all the filenames in the directory. Maybe this is as good as it's going to get, but it would be great to know if there is a better way. Jonny. On 13 Nov 2015, at 16:54, Gary L. Wade <garyw...@desisoftsystems.com> wrote: > Try going down a level to the BSD layer APIs for directory contents traversal. > -- > Gary L. Wade (Sent from my iPad) > http://www.garywade.com/ > >> On Nov 13, 2015, at 8:28 AM, Jonathan Taylor <jonathan.tay...@glasgow.ac.uk> >> wrote: >> >> Hi all, >> >> I want to be able to identify quickly (programatically) how many image files >> reside in a particular directory. At present I call: >> [NSFileManager defaultManager] contentsOfDirectoryAtPath:dir error:nil]; >> and then examine the type suffixes (which in comparison is very quick). When >> looking at a directory over a network or on an external drive, the >> NSFileManager call can take several seconds for a directory containing 18k >> files of which half are images. >> >> These sorts of numbers are in fact a common use case for me, and I would >> like to avoid this delay. This is for preview information in an NSOpenPanel, >> so I don't want to make things this unresponsive - but at the same time it >> is very useful to have access to this information for the preview. >> >> Can anybody advise on a quicker way of achieving what I want to achieve? The >> fact that 'ls' takes almost as long makes me think this is probably a fairly >> insurmountable problem, but at the same time the quantity of information >> transferred (of the order of 200k of data) should not take 2 seconds to >> transfer, so in that sense it doesn't seem unreasonable to try and see if >> there is a faster way. >> >> I would prefer to get the filenames themselves, but I could settle for just >> a count of the total number of files (of any kind) in the directory *and* >> the ability to get the paths of just the first few files in the directory, >> if there might be a faster way of doing that. >> >> Thanks for any suggestions >> Jonny ___ 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
Identify image file count in directory
Hi all, I want to be able to identify quickly (programatically) how many image files reside in a particular directory. At present I call: [NSFileManager defaultManager] contentsOfDirectoryAtPath:dir error:nil]; and then examine the type suffixes (which in comparison is very quick). When looking at a directory over a network or on an external drive, the NSFileManager call can take several seconds for a directory containing 18k files of which half are images. These sorts of numbers are in fact a common use case for me, and I would like to avoid this delay. This is for preview information in an NSOpenPanel, so I don't want to make things this unresponsive - but at the same time it is very useful to have access to this information for the preview. Can anybody advise on a quicker way of achieving what I want to achieve? The fact that 'ls' takes almost as long makes me think this is probably a fairly insurmountable problem, but at the same time the quantity of information transferred (of the order of 200k of data) should not take 2 seconds to transfer, so in that sense it doesn't seem unreasonable to try and see if there is a faster way. I would prefer to get the filenames themselves, but I could settle for just a count of the total number of files (of any kind) in the directory *and* the ability to get the paths of just the first few files in the directory, if there might be a faster way of doing that. Thanks for any suggestions Jonny ___ 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: Lost memory, GCD, dispatch sources, Cocoa bindings & User interface
Hi Jean, A wild guess that might or might not have any relevance to your problem: I see that you are wrapping your blocks with an autorelease pool, and that reminded me of a problem I dealt with a while back. As I understand it (and as discussed on this list some while back I think) pools may not always be drained when you expect. I'm not sure if that applies to explicitly generated ones, but it certainly seems to apply to little snippets of callback code (e.g. UI accessors) that may be called from within the main event loop. I have a dim recollection there may be some funny stuff with GCD-related code as well. Anyway, I have the following little bit of code in my application. I don't remember all the details now, so the comment itself (and perhaps a trawl through the list archives for that text) will have to serve as an explanation: // Create a periodic timer that "tickles" the main event loop to drain autorelease pools. // Response from cocoa-dev discussion was that: // This is a long-standing problem with AppKit. According to the documentation, // "The Application Kit creates an autorelease pool on the main thread at the // beginning of every cycle of the event loop, and drains it at the end, thereby // releasing any autoreleased objects generated while processing an event." // However, this is somewhat misleading. The "end" of the event loop cycle is // immediately before the beginning. Thus, for example, if your app is in the background // and not receiving events, then the autorelease pool will not be drained. That's why // your memory drops significantly when you click the mouse or switch applications. [JDispatchTimer allocRepeatingTimerOnQueue:dispatch_get_main_queue() atInterval:5.0 withHandler:^{ NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint modifierFlags:0 timestamp:[NSDate timeIntervalSinceReferenceDate] windowNumber:0 context:nil subtype:0 data1:0 data2:0]; [NSApp postEvent:event atStart:YES]; }]; I wonder if that would be any help with your case - either for the exact reasons I encountered, or for some reason along similar lines. It just might be a wild stab in the dark at a quick (but obscure) fix, but if it doesn't help then I guess you'll have to start exploring things with Instruments as others have suggested. Cheers Jonny ___ 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
KVO detection of changes to selection in NSOpenPanel
I’ve just noticed a glitch where my custom file preview box in an NSOpenPanel works fine on OS X 10.9.5 but does not get updated on 10.8.5. Specifically, I declare a dependency of my property on panel.filenames, panel.URL and panel.directoryURL (just to see if ANY of them fire), and none of them are getting prodded when the user changes the selected file/directory. Does anybody know if this is expected behaviour? I did notice somewhere buried in here: https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKitOlderNotes/#X10_9Notes that it says (for OS X 10.9) Key Value Observation compliance was dramatically increased for public and some private properties of actual, non sandboxed NSOpen and Save panels, including keys affecting other values. For example, if the directory value changes on a save panel, this will cause a KVO notification to be emitted for the URL value as well as the directory value. Sandboxed NSOpen and Save Panels do not have the same level of KVO compliance. This does make me wonder if I should perhaps not be surprised that my use of keyPathsAffectingValueForKey is not going well, although nothing in that statement seems to specifically preclude what I am doing from working on 10.8. Does anyone know if there’s any hope of my KVO approach working? The alternative seems to be to implement a delegate method for panelSelectionDidChange. Would that be the sensible way to deal with this, or is there a third and better way I should be using? Cheers Jonny ___ 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: How to resize accessory view to match Open panel
Well, I think I have bumbled my way towards a working solution that seems to work (tested on OS 10.9), although this was largely through trial and error and so might not be the best way of doing things. Thankyou very much to everyone who offered help on and off list. One indirect clue I found was here: http://stackoverflow.com/questions/27374355/nssavepanel-crashes-on-yosemite (I encountered the same issue if I set translatesAutoresizingMaskIntoConstraints=NO in the nib itself) Another was the failure of my attempts to manually set my own constraints on my view, after adding it to the NSOpenPanel. As far as I can tell, the act of adding it causes NSOpenPanel to apply some fairly aggressive auto-constraints, and I didn’t manage to work out how I could override them. That might somewhat explain why my attempts to change things in my nib file weren’t having much effect - I suspect that NSOpenPanel is specifically overriding certain properties with ones it has chosen itself. Anyway, long story short: AFTER adding the view as openPanel.accessoryView, I manually set the view rectangle to fill its parent view, and then I do: viewController.view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;// Must be done AFTER adding as accessory view This seems to result in the behaviour I want (my view fills the available space, and scales as the window is resized). This works regardless of whether the nib itself is set to autolayout or not. Hopefully that information might be of some use for posterity. Cheers Jonny On 9 Jul 2015, at 16:18, Ken Thomases k...@codeweavers.com wrote: On Jul 9, 2015, at 7:05 AM, Jonathan Taylor jonathan.tay...@glasgow.ac.uk wrote: I gave it a try, setting what I thought should be needed, but it doesn’t seem to be having the desired effect as yet. I have the nib file set to “Use autolayout”, and have included the code you quoted. Even in a NIB set to use auto layout, top-level views have translatesAutoresizingMaskIntoConstraints turned on. So, you should turn it off in the NIB on the Attributes inspector or in code after you've loaded it, if the open panel is expected to be auto-layout-savvy. (In general, actually, one should leave it on and let the code which places the view into a larger hierarchy decide whether to turn it off. But maybe turning it off will work for this case. I don't know.) Regards, Ken ___ 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: How to resize accessory view to match Open panel
On 9 Jul 2015, at 16:18, Ken Thomases k...@codeweavers.com wrote: On Jul 9, 2015, at 7:05 AM, Jonathan Taylor jonathan.tay...@glasgow.ac.uk wrote: I gave it a try, setting what I thought should be needed, but it doesn’t seem to be having the desired effect as yet. I have the nib file set to “Use autolayout”, and have included the code you quoted. Even in a NIB set to use auto layout, top-level views have translatesAutoresizingMaskIntoConstraints turned on. So, you should turn it off in the NIB on the Attributes inspector or in code after you've loaded it, if the open panel is expected to be auto-layout-savvy. (In general, actually, one should leave it on and let the code which places the view into a larger hierarchy decide whether to turn it off. But maybe turning it off will work for this case. I don't know.) Interestingly, setting it in the NIB did not go well: *** Assertion failure in -[NSImageView _didChangeHostsAutolayoutEngineTo:], /SourceCache/AppKit/AppKit-1265.21/Layout.subproj/NSView_Layout.m:510 An uncaught exception was raised Should translate autoresizing mask into constraints if _didChangeHostsAutolayoutEngineTo:YES. I guess as you say the runtime is very keen for me to leave it on! It’s conceivable that my problem is that I am not doing something important related to autolayout (which is new to me), though I am not sure what it could be. I am giving the view a low content-hugging priority (“the priority with which it RESISTS being made larger/smaller than its intrinsic size”) in case that would make any difference (it doesn’t). I have tried both with the text control and with an NSImageView (just in case that makes any difference). In the imageview case, the intrinsic size of the view is very small, and it is very happy to resize itself to the frame rectangle that I have no choice but to define for it in IB. However it is utterly refusing to undergo any other resizing in order to fill the size of the parent view that it has been inserted into in the NSOpenPanel. If people weren’t saying that they had managed to get accessory views to resize according to the width of the parent view (over which I don’t have control, of course), then I’d assume it wasn’t possible. However since it apparently is possible I’m tearing my hair out over this, trying to work out what I am missing. I don’t suppose anybody knows of any examples that definitely demonstrate this working? Cheers Jonny ___ 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: How to resize accessory view to match Open panel
Thanks very much for your reply. I did wonder if autolayout might make life easier - that’s something I haven’t delved into before. I gave it a try, setting what I thought should be needed, but it doesn’t seem to be having the desired effect as yet. I have the nib file set to “Use autolayout”, and have included the code you quoted. Doesn’t seem to have any effect. I am loading a nib which contains just an NSTextField, which I have given a red background to make it clear what its extent is. As you can see from this screenshot, the text field is retaining its shape as defined in the nib and is not resizing as I would like it to, to match the size of the parent window. http://imgur.com/aWN4cGU It may be that I am doing something wrong related to autolayout (although this was exactly the problem I was having with non-autolayout as well…). Do you have any thoughts about what I might be missing in order for this to behave as I would like? Cheers Jonny On 8 Jul 2015, at 22:44, Lee Ann Rucker lruc...@vmware.com wrote: My accessory views use autolayout and that seems to work fine in 10.9 and up. In 10.8, you need [accessoryView layoutSubtreeIfNeeded]; if (floor(NSAppKitVersionNumber) = NSAppKitVersionNumber10_8) { [accessoryView setTranslatesAutoresizingMaskIntoConstraints:YES]; } On Jul 8, 2015, at 8:33 AM, Jonathan Taylor jonathan.tay...@glasgow.ac.uk wrote: I feel this should be a simple question, but I cannot find an answer that works. I have an open panel to which I am trying to add an accessory view. That much works. However I would like the accessory view to resize to fit the width of the parent window. It’s just a textual description, after all. An old thread here: https://urldefense.proofpoint.com/v2/url?u=http-3A__www.cocoabuilder.com_archive_cocoa_106875-2Dsetaccessoryview.htmld=BQIGaQc=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw-YihVMNtXt-uEsr=ie7S-J__EKnfyVOBV7-jV2rZ--p47O6vkyTklpDM3h4m=cHbQmyTJpg2XJFwD6Ij_z3NjqhIEgWWn9zXrnGjjOxks=MuBFc9loNUfef9MsVOB-rZbhMfX4JwFpjj8iB_S-OzUe= suggests this is not trivial to do. I have tried the suggested monitoring of NSWindowDidResizeNotification (and also tried NSViewFrameDidChangeNotification), and these don’t seem to work quite right. There have been plenty of OS changes since that thread was written, so probably no surprises there. What happens is that it doesn’t seem possible to *shrink* the Open window (I guess the ‘hard’ size that I am setting for my view is affecting the minimum size of the overall window) and, much more alarmingly, I get crashes when resizing. The alternative suggestion related to IB struts doesn’t seem to work for me either. I set all four edge struts and tried both with and without the ‘resizeable’ arrows in the middle of the view. No effect. Can anyone advise on the current and correct way of getting the accessory view to resize appropriately? It seems this should be a common desired behaviour, but haven’t had any luck doing it or finding any recent examples/advice on google… Thanks Jonny ___ 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/lrucker%40vmware.com This email sent to lruc...@vmware.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
How to resize accessory view to match Open panel
I feel this should be a simple question, but I cannot find an answer that works. I have an open panel to which I am trying to add an accessory view. That much works. However I would like the accessory view to resize to fit the width of the parent window. It’s just a textual description, after all. An old thread here: http://www.cocoabuilder.com/archive/cocoa/106875-setaccessoryview.html suggests this is not trivial to do. I have tried the suggested monitoring of NSWindowDidResizeNotification (and also tried NSViewFrameDidChangeNotification), and these don’t seem to work quite right. There have been plenty of OS changes since that thread was written, so probably no surprises there. What happens is that it doesn’t seem possible to *shrink* the Open window (I guess the ‘hard’ size that I am setting for my view is affecting the minimum size of the overall window) and, much more alarmingly, I get crashes when resizing. The alternative suggestion related to IB struts doesn’t seem to work for me either. I set all four edge struts and tried both with and without the ‘resizeable’ arrows in the middle of the view. No effect. Can anyone advise on the current and correct way of getting the accessory view to resize appropriately? It seems this should be a common desired behaviour, but haven’t had any luck doing it or finding any recent examples/advice on google… Thanks Jonny ___ 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: Custom NSView subclass - expressing the fact that a property affects the displayed image
The closest I got was creating a macro that uses np_thread_main() (or whatever it was called exactly, it’s part of the pthreads API, IIRC) and throws if it’s not the main thread. I call that e.g. in observeValueForKeyPath overrides whenever I make thread-unsafe calls, so I don’t accidentally make a threaded call. Ah, that's a good idea. I had wanted to do something like that but had been put off by the very large number of possible entry points. observeValueForKeyPath is a great idea that is sure to fire if any GUI-bound properties change. Of course, it’s only a runtime check, but it’s better than nothing. Sure would be fine if the Static Analyzer could be made to understand KVO and threading and complain about such uses. I have a suspicion that if you can get the static analyzer to understand that then you have probably solved a number of officially Hard problems along the way! ___ 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: Custom NSView subclass - expressing the fact that a property affects the displayed image
On 23 May 2015, at 00:21, Graham Cox graham@bigpond.com wrote: My advice is: forget it. What you’re doing is fine, and it’s the normal way to make views repaint when a property changes. It’s not code ‘bloat’ either - @synthesize produces code just as if you’d written it yourself. Any other way than simply adding a call to -setNeedsDisplay: is MORE code than that. Just to be clear, I meant source code bloat - in the process of refactoring the code I have been rather horrified at how much of my codebase is really just glue code for user interface stuff, in what should be just a GUI wrapper on some scientific code. What would be quite nice (though maybe too much of a special case and very unlikely to happen) is a qualifier for properties that would add the -setNeedsDisplay: automatically as part of the @synthesize, but I doubt that will ever happen because it a) only pertains to views b) might not be optimal for some situations, where only part of the view needs updating, and c) made somewhat redundant by layers, which have a flag that causes a redisplay on a property change. Ah, now it sounds like layers could be something I should be reading up on then! Maybe another one of those cases of me asking the wrong question because I don't know what the right one is... All of you wrote: Since you're talking about properties on an NSView subclass, and NSView is documented as being not thread-safe, the atomicity thing sounds like a big red herring (or red flag, depending on your preference for fish or cloth). [rambling off the original topic...] You are quite right of course. If I am concerned about atomicity on this particular object then I am definitely doing something wrong. There was probably some end-of-week thinking behind what I did, but the rough train of thought went: - There is necessarily a fair bit of multithreading in my codebase, and I have not found a completely foolproof way of guaranteeing it remains isolated from GUI code (though I know I must do that). I want to use [non-gui-related] properties on other threads, but then sooner or later I end up accidentally causing an interaction with GUI-bound properties and causing an obscure and hard-to-debug crash - A recent such crash involved a double-free of an NSNumber (where to begin looking...!?), and brainstorming this lead me to imagine that accessing a nonatomic property returning an objc object could lead to that happening. - As a result I decided I had no good reason to have any nonatomic properties, and that I would try and remove any use of nonatomic rather than try and decide on a case-by-case basis - This led to warnings about custom setters paired with auto-synthesized getters, which got me looking at this setNeedsDisplay code and wondering if there was a better way of doing that anyway. Probably an overreaction (and very probably not the actual cause of the crash), but I was pretty sure that technically speaking my universal use of nonatomic [for reasons lost in the mists of time] was not correct. If only there was a way of annotating properties as only-to-be-used-from-the-main-thread. I've asked something to that effect previously, though, and nobody had any suggestions. I feel there must be a way of designing-in the safety that I need, but I haven't worked out what it might be. ___ 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
Custom NSView subclass - expressing the fact that a property affects the displayed image
I’m trying to think if there is an elegant way of handling the situation I find in some of my display code. I have a class which inherits from NSView and which overrides drawRect. The class has a number of properties, and if they change then the view needs redrawing. At present I have custom setters that call through to setNeedsDisplay:YES. This results in quite a lot of code bloat (since I would otherwise just @synthesize the properties and be done with it). I could set an observer on each property, but that would be a bit tedious (especially since, as I understand it, I have to remove EACH of the observers individually as well on dealloc). I am trying to think if there is a way I can leverage keyPathsForValuesAffectingValueForKey to make things a bit simpler. I’m quite a fan of using that where I can. It would be great if I could say that all my properties affect some particular property of NSView that would trigger a redraw. I can’t think of one that would do the trick, though. [If you think about it, the property needsDisplay is NOT the one I want to say is affected by my keys…] I could create a single “dummy” property of my own, say that changes to all these other properties affect that key, and then monitor that single key using KVO (and call setNeedsDisplay whenever it gets “tickled” by some other property change). That would do what I want, but feels a little bit hacky. Does anybody have any thoughts about what I might do? I feel this is probably a relatively common problem that people must have a way of dealing with… Cheers Jonny ___ 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: Custom NSView subclass - expressing the fact that a property affects the displayed image
Thanks for your reply Mike: Well you could have a single key which you observe internally, and which all the other keys feed into. Whenever it “changes”, treat that as time to mark as needing display. That way you’re asking AppKit to do the work of creating all the other observations for you. I think this is what I was describing here, isn’t it (or am I misunderstanding you?): I could create a single “dummy” property of my own, say that changes to all these other properties affect that key, and then monitor that single key using KVO (and call setNeedsDisplay whenever it gets “tickled” by some other property change). That would do what I want, but feels a little bit hacky. It all seems rather wasteful though. You’ve added a couple of layers of indirection into the system to save a handful of lines of code. Is it really that big a deal to write some custom setters? They’re only four lines long each. I agree that it’s extra indirection, but since performance is never going to be an issue, I feel it’s a slight gain on tidiness and maintainability. I agree that it’s not a big deal for one property, but when there are lots it starts to add up. And it’s not just the setters - what finally spurred me into action was the decision that I wanted all my properties to be atomic (which may or may not be related to an occasional crash I have been seeing). That means writing a correct threadsafe getter for each one as well... ___ 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: NSNotificationQueue Question
I have a bit of code that posts notifications to coalescing notification queue. [...] In another place I need to force the notification queue to issue a did change notification. This works but the problem is that there are undesirable side effects to running the runloop once when this call is made. What I would like to do is to run the runloop once but only cause the notification queue to post this notification but not do other things. Is that definitely the way you need to do it, or would you be happy with pulling the notifications from the queue using dequeueNotificationsMatching, and then reposting with NSPostASAP or NSPostNow? ___ 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: NSNotification coalescing - which one gets through?
Thanks for your replies Seth: I am trying to work out whether there are any rules that define which of multiple NSNotifications combined using coalescing actually get through to the receivers, and preferably a way of controlling that behaviour. This becomes relevant if for example there is different UserInfo associated with each object. I can’t find any specific statement about what the behaviour is under these circumstances. My interpretation of the API is that user info should either be consistent or not used in coalescing scenarios, though the documentation never discusses this. Hmm, that's a good point. Actually I think I may have answered my own question: calling dequeueNotificationsMatching immediately before posting a new notification seems to do the trick. This seems like a reasonable and logical way of achieving what I want. Can anyone see any problem with doing that? Nope. Seems fine to me. On further consideration I do wonder, in a case where some notifications were treated in this way and other different notifications weren't, whether the ones I did treat this way would end up effectively being treated as *even* lower priority than the ones that weren't (by constantly being relegated to the back of the event queue). Shouldn't be a problem in my case though, as I am going to treat all coalesced+postWhenIdle events the same way. The other way to accomplish is this is to have the data stored outside of the notification and accessible to the receivers, and just let the notifications coalesce as normal. Instead of looking in userInfo, the receivers would go pull the data from the other source. But whether that's a better fit is questionable based on circumstances. Yes, in fact that's basically the setup I had previously, and wanted to move away from. Rightly or wrongly, I decided I would prefer to avoid having a whole load of state and properties whose sole purpose (as it turned out) was to be queried in response to notifications. That also felt like a slightly awkward compromise between a tightly coupled scenario using KVO and a weakly coupled scenario using notifications to classes that don't need to know anything about the originating class - I liked the idea of things being as decoupled as possible. ___ 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: NSNotification coalescing - which one gets through?
Actually I think I may have answered my own question: calling dequeueNotificationsMatching immediately before posting a new notification seems to do the trick. This seems like a reasonable and logical way of achieving what I want. Can anyone see any problem with doing that? On 6 May 2015, at 11:54, Jonathan Taylor jonathan.tay...@glasgow.ac.uk wrote: I am trying to work out whether there are any rules that define which of multiple NSNotifications combined using coalescing actually get through to the receivers, and preferably a way of controlling that behaviour. This becomes relevant if for example there is different UserInfo associated with each object. I can’t find any specific statement about what the behaviour is under these circumstances. A concrete example: frames are received from a video camera, and a notification (with coalescing) is sent when each one arrives (with a pointer to the actual frame object in the user data of the NSNotification). Listeners may wish to update their own displayed image if spare cycles are available. However a quick experiment suggests that the EARLIEST-posted notification is the one that survives coalescing. That means that receivers are acting on stale information. No doubt there are some different circumstances where it might make sense to keep the earliest-posted notification, but in this case I’d definitely like the most-recently posted to make it through. I can think of several ways of achieving what I want with the help of additional code, but is there any way I can get the NSNotification infrastructure to behave the way I want (coalescing keeps the most recently-posted notification and discards older ones)? Thanks for any suggestions! Jonny. ___ 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
NSNotification coalescing - which one gets through?
I am trying to work out whether there are any rules that define which of multiple NSNotifications combined using coalescing actually get through to the receivers, and preferably a way of controlling that behaviour. This becomes relevant if for example there is different UserInfo associated with each object. I can’t find any specific statement about what the behaviour is under these circumstances. A concrete example: frames are received from a video camera, and a notification (with coalescing) is sent when each one arrives (with a pointer to the actual frame object in the user data of the NSNotification). Listeners may wish to update their own displayed image if spare cycles are available. However a quick experiment suggests that the EARLIEST-posted notification is the one that survives coalescing. That means that receivers are acting on stale information. No doubt there are some different circumstances where it might make sense to keep the earliest-posted notification, but in this case I’d definitely like the most-recently posted to make it through. I can think of several ways of achieving what I want with the help of additional code, but is there any way I can get the NSNotification infrastructure to behave the way I want (coalescing keeps the most recently-posted notification and discards older ones)? Thanks for any suggestions! Jonny. ___ 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: User interface unresponsive in window
Am I right in thinking that when running under Xcode any drawing errors will be logged to the Xcode console? No, not unless they’re actually exceptions. Messages from other processes are only going to appear in the system log. OK, thanks for your suggestion about checking the system log then - I will look out for that. With puzzling, intermittent errors like this, I often find that reading your own code carefully may be more productive than going to heroic debugging extremes. The trick is not to prejudge *where* in your code you should look. (Don’t be the person looking underneath the street light for a dropped quarter because “that’s where the light is”.) That's a fair suggestion, but taken in its most general sense that is a near-impossible task. There are 100-odd source files in the project, etc, and just code-read the project and look for some bug is a non-starter. Are you effectively saying that you agree with my hypothesis that the cause is GUI-related code being executed on a non-main thread? If you or others have definitely seen that cause problems of this sort in the past, then I'll certainly do a second more thorough read-through of any code that could possibly be relevant... Cheers Jonny ___ 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
User interface unresponsive in window
I've started encountering intermittent problems in one specific window in my application, where text input boxes become unresponsive, steppers remain highlighted after clicking, etc. I'm rather short of ideas on how to debug this, particular since I haven't worked out how to reproduce it reliably. Other windows seem to remain unaffected. From dimly-remembered past experience I have a feeling it could be related to something somewhere resulting in GUI code being executed on a non-main thread. There is in principle a risk of that, since the window interacts with peripherals/drivers etc involving multithreaded code. I've tried to isolate the GUI code from the multithreaded code, but may perhaps have missed some obscure case. [ideally, I'd probably totally isolate anything multithreaded from ObjC code, but that would mean a proliferation of shadow classes, which is something I'd prefer to avoid being dragged into] Even if my suspicion about the cause (multithreading+GUI) is correct, I'm still not sure how to pin down and debug the problem, since there are so many entry points into GUI-related code (e.g. property value changes), not all of which even involve my own code directly. It would be great if there was some way of enabling a global exception if main-thread requirements are violated, but I certainly haven't heard of such a thing (and can imagine there could be very good reasons why it would be prohibitively hard to implement). Can anyone suggest ways to diagnose and debug my problem (or indeed suggest other possible causes I haven't thought of)? Thanks in advance Jonny ___ 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: User interface unresponsive in window
Thanks for the suggestions. Am I right in thinking that when running under Xcode any drawing errors will be logged to the Xcode console? That's certainly what I've seen in the past (but not in relation to this problem - haven't seen anything in the Xcode console at all for this). Any other ideas from anyone? Has anybody seen similar symptoms ever in the past (GUI not responding properly in one single window)? On 15 Apr 2015, at 18:01, Quincey Morris quinceymor...@rivergatesoftware.com wrote: On Apr 15, 2015, at 07:04 , Jonathan Taylor jonathan.tay...@glasgow.ac.uk wrote: From dimly-remembered past experience I have a feeling it could be related to something somewhere resulting in GUI code being executed on a non-main thread. You can at least start by trying the simple things, if you haven’t tried them already: — Make sure you have an Objc-C exception breakpoint set in Xcode at all times. — Use the Console utility to look in the system log for errors about incorrect drawing calls in your app. There’s not much chance this will get you off easily, but it’s a quick start. ___ 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
Text fields bound to numerical property - commas in number
I've come back to some old code that I haven't used for a while, and in the meantime I've done several OS upgrades and Xcode upgrades so plenty has changed, but my code is behaving in a strange way that I'm sure it didn't used to. I have a text field in my GUI bound to a property of type 'double'. The text field does not have any explicit number formatter attached to it. When I set the property e.g. to 22000 then it appears in the text field as: 22,000 OK, fair enough, maybe the default formatting behaviour of text fields has changed. The problem is that when I alter that value (but leaving it in the same style), so for example I change it to: 22,001 then the value of my property is set to 22. In other words, the comma is not being parsed correctly to treat the whole text string as a number. This behaviour seems very strange and inconsistent. Is this something that people are familiar with? I imagine I could solve this by putting an explicit number formatter on every text field, but I have rather a lot of them and so would prefer not to do this! I'm also concerned that this is indicative of some subtler underlying problem that I should maybe understand rather than hide. Can anyone advise at all? Cheers Jonny. ___ 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: NSPathControl (popup) - programatically show Choose dialog
On 17 Mar 2015, at 10:36, dangerwillrobinsondan...@gmail.com wrote: Have you tried just displaying an NSOpenPanel yourself then setting the selected URL returned to the path control's URL property? I have now, and that certainly is one way of doing it. I have three (minor) reasons for preferring not to do it this way: - It requires a certain amount of code duplication, to customize the dialog the path control throws up, and to customize my own one. - I quite like the idea of the visual feedback of flashing up the path control menu to make it clear that the open dialog is associated with that control - Given that the delegate method pathControl:willPopUpMenu exists, I just can't quite believe that there isn't a counterpart -popUpMenu command. It very much seems like there isn't, though! I should probably just go with your suggestion and move on, I just find it a little bit puzzling that there doesn't seem to be a way of doing what I had hoped... Cheers Jonny On 2015/03/17, at 19:16, Jonathan Taylor jonathan.tay...@glasgow.ac.uk wrote: OK, I've got part of the way to a solution, but haven't got it fully working yet. Perhaps the weekday crowd here can advise? I've realised that I can get my path control to performClick: // When adding a new sequence we immediately prompt the user to select a folder to use for image files simulatingPathControlClick = true; [folderSelectPopup performClick:self]; simulatingPathControlClick = false; This is a good start, because I see my delegate function being called: -(void)pathControl:(NSPathControl*)pathControl willPopUpMenu:(NSMenu*)menu { if (simulatingPathControlClick) { [menu performActionForItemAtIndex:0]; } } This seems to be the only way of getting access to the menu (folderSelectPopup.menu always seems to return nil...). Now that I have access to the menu I can get it to performActionForItemAtIndex. That is basically what I'm trying to do here. However it doesn't quite work as it should. The code as written here brings up the Open dialog, which works as intended, but I am calling it sooner than I should (in willPopUpMenu; the menu has not yet popped up!). As a result, after the user dismisses the Open dialog, THEN the choose menu on the path control pops up, which is annoying and illogical for the user. If alternatively I wrap the performClick in a dispatch_async on the main thread (i.e. it should execute after the menu pops up) then something weird happens - the menu appears and then the Open dialog pops up (as I had hoped), but no file system items appear in there. I have a suspicion this has something to do with funny run-loop states when tracking menus, but I don't know what to do about it! I don't know if what I am trying to do is an appropriate way of going about things, but hopefully it gives a clearer idea of what I am trying to achieve here (bring up the Open dialog, just as if the user had selected Choose... themselves). And hopefully somebody can suggest how I should tweak what I am doing so it behaves correctly? Thanks again Jonny On 15 Mar 2015, at 13:18, Jonathan Taylor jonathan.tay...@glasgow.ac.uk wrote: I have a dialog which allows the user to select a folder containing data to be processed, set various parameters that affect the processing, and displays the result of the analysis. There is an NSPathControl (popup) to select the folder. Inevitably the first thing the user does is choose a folder (and of course they have the option of changing this later). I would like to simplify the workflow by automatically popping up the open dialog when the main dialog is first opened, as if the user has clicked on the path popup and selected choose. However, I can't work out an obvious way of triggering the path control to behave as if the user has manually selected choose from the popup. Is there a way I can do that? I could of course throw up my own open dialog and programatically set the URL associated with the path control, but that seems like unnecessary duplication of code when I could just call something like [myPathControl displayChooseDialog] (if such a method existed!). Can anyone suggest a way of doing what I want here? Thanks for any suggestions Jonny ___ 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/dangerwillrobinsondanger%40gmail.com This email sent to dangerwillrobinsondan...@gmail.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
Re: NSPathControl (popup) - programatically show Choose dialog
On 17 Mar 2015, at 10:53, dangerwillrobinsondan...@gmail.com wrote: Also see the sample code. It's a lot easier to see how the API is expected to be used. The docs are a little thin in their descriptions. https://developer.apple.com/library/mac/samplecode/ObjectPath/Introduction/Intro.html Thanks very much for pointing me to that, that's interesting. However, it does rather emphasize my point about consistency between programatically bringing up the Open dialog and doing it through the path control. In that demo code, if you set the control type to 'popup' then: - Clicking on set path brings up an open panel on the window, that has been customized with the word Choose, etc - Clicking on the path popup and selecting Choose brings up an open dialog that has been customized using a separate chunk of duplicated code. Well the sample code illustrates that the delegate method should be the place to configure the open panel. As I say, there are two separate places in the code where the configuring takes place, to handle these two different ways of setting the path. I just feel it would be nice if set path could trigger the same code as going through the path popup. The fact that Apple's own sample code doesn't do this is certainly a good hint that it probably isn't meant to be possible, though! On 2015/03/17, at 19:36, dangerwillrobinsondan...@gmail.com wrote: Have you tried just displaying an NSOpenPanel yourself then setting the selected URL returned to the path control's URL property? Sent from my iPhone On 2015/03/17, at 19:16, Jonathan Taylor jonathan.tay...@glasgow.ac.uk wrote: OK, I've got part of the way to a solution, but haven't got it fully working yet. Perhaps the weekday crowd here can advise? I've realised that I can get my path control to performClick: // When adding a new sequence we immediately prompt the user to select a folder to use for image files simulatingPathControlClick = true; [folderSelectPopup performClick:self]; simulatingPathControlClick = false; This is a good start, because I see my delegate function being called: -(void)pathControl:(NSPathControl*)pathControl willPopUpMenu:(NSMenu*)menu { if (simulatingPathControlClick) { [menu performActionForItemAtIndex:0]; } } This seems to be the only way of getting access to the menu (folderSelectPopup.menu always seems to return nil...). Now that I have access to the menu I can get it to performActionForItemAtIndex. That is basically what I'm trying to do here. However it doesn't quite work as it should. The code as written here brings up the Open dialog, which works as intended, but I am calling it sooner than I should (in willPopUpMenu; the menu has not yet popped up!). As a result, after the user dismisses the Open dialog, THEN the choose menu on the path control pops up, which is annoying and illogical for the user. If alternatively I wrap the performClick in a dispatch_async on the main thread (i.e. it should execute after the menu pops up) then something weird happens - the menu appears and then the Open dialog pops up (as I had hoped), but no file system items appear in there. I have a suspicion this has something to do with funny run-loop states when tracking menus, but I don't know what to do about it! I don't know if what I am trying to do is an appropriate way of going about things, but hopefully it gives a clearer idea of what I am trying to achieve here (bring up the Open dialog, just as if the user had selected Choose... themselves). And hopefully somebody can suggest how I should tweak what I am doing so it behaves correctly? Thanks again Jonny On 15 Mar 2015, at 13:18, Jonathan Taylor jonathan.tay...@glasgow.ac.uk wrote: I have a dialog which allows the user to select a folder containing data to be processed, set various parameters that affect the processing, and displays the result of the analysis. There is an NSPathControl (popup) to select the folder. Inevitably the first thing the user does is choose a folder (and of course they have the option of changing this later). I would like to simplify the workflow by automatically popping up the open dialog when the main dialog is first opened, as if the user has clicked on the path popup and selected choose. However, I can't work out an obvious way of triggering the path control to behave as if the user has manually selected choose from the popup. Is there a way I can do that? I could of course throw up my own open dialog and programatically set the URL associated with the path control, but that seems like unnecessary duplication of code when I could just call something like [myPathControl displayChooseDialog] (if such a method existed!). Can anyone suggest a way of doing what I want here? Thanks for any suggestions Jonny ___ Cocoa-dev mailing list
Re: NSPathControl (popup) - programatically show Choose dialog
OK, I've got part of the way to a solution, but haven't got it fully working yet. Perhaps the weekday crowd here can advise? I've realised that I can get my path control to performClick: // When adding a new sequence we immediately prompt the user to select a folder to use for image files simulatingPathControlClick = true; [folderSelectPopup performClick:self]; simulatingPathControlClick = false; This is a good start, because I see my delegate function being called: -(void)pathControl:(NSPathControl*)pathControl willPopUpMenu:(NSMenu*)menu { if (simulatingPathControlClick) { [menu performActionForItemAtIndex:0]; } } This seems to be the only way of getting access to the menu (folderSelectPopup.menu always seems to return nil...). Now that I have access to the menu I can get it to performActionForItemAtIndex. That is basically what I'm trying to do here. However it doesn't quite work as it should. The code as written here brings up the Open dialog, which works as intended, but I am calling it sooner than I should (in willPopUpMenu; the menu has not yet popped up!). As a result, after the user dismisses the Open dialog, THEN the choose menu on the path control pops up, which is annoying and illogical for the user. If alternatively I wrap the performClick in a dispatch_async on the main thread (i.e. it should execute after the menu pops up) then something weird happens - the menu appears and then the Open dialog pops up (as I had hoped), but no file system items appear in there. I have a suspicion this has something to do with funny run-loop states when tracking menus, but I don't know what to do about it! I don't know if what I am trying to do is an appropriate way of going about things, but hopefully it gives a clearer idea of what I am trying to achieve here (bring up the Open dialog, just as if the user had selected Choose... themselves). And hopefully somebody can suggest how I should tweak what I am doing so it behaves correctly? Thanks again Jonny On 15 Mar 2015, at 13:18, Jonathan Taylor jonathan.tay...@glasgow.ac.uk wrote: I have a dialog which allows the user to select a folder containing data to be processed, set various parameters that affect the processing, and displays the result of the analysis. There is an NSPathControl (popup) to select the folder. Inevitably the first thing the user does is choose a folder (and of course they have the option of changing this later). I would like to simplify the workflow by automatically popping up the open dialog when the main dialog is first opened, as if the user has clicked on the path popup and selected choose. However, I can't work out an obvious way of triggering the path control to behave as if the user has manually selected choose from the popup. Is there a way I can do that? I could of course throw up my own open dialog and programatically set the URL associated with the path control, but that seems like unnecessary duplication of code when I could just call something like [myPathControl displayChooseDialog] (if such a method existed!). Can anyone suggest a way of doing what I want here? Thanks for any suggestions Jonny ___ 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
NSPathControl (popup) - programatically show Choose dialog
I have a dialog which allows the user to select a folder containing data to be processed, set various parameters that affect the processing, and displays the result of the analysis. There is an NSPathControl (popup) to select the folder. Inevitably the first thing the user does is choose a folder (and of course they have the option of changing this later). I would like to simplify the workflow by automatically popping up the open dialog when the main dialog is first opened, as if the user has clicked on the path popup and selected choose. However, I can't work out an obvious way of triggering the path control to behave as if the user has manually selected choose from the popup. Is there a way I can do that? I could of course throw up my own open dialog and programatically set the URL associated with the path control, but that seems like unnecessary duplication of code when I could just call something like [myPathControl displayChooseDialog] (if such a method existed!). Can anyone suggest a way of doing what I want here? Thanks for any suggestions Jonny ___ 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 to selection of NSArrayController
Hi all, I feel this should be a very simple question, but I am struggling with it - the tutorials and online info I can find is either 5 years out of date or seem to imply that I am doing everything right! In my code I have an NSMutableArray of “message” objects, each with a number of properties defined on them. In the GUI this is wired up to a table view, via an NSArrayController. That all seems to work fine, and the object properties are listed in the table[*]. Underneath the table I want to display some more detailed information about the currently-selected object in the table. I would have thought that I could do this just by binding the relevant NSTextField to MessageArray.selection.myExtendedInformationProperty. This works up to a point, in that I do see text appearing in the text field. However it does not update when the selection in the table view changes, which is what I had intended to happen. This is basically what happens on p18 of this tutorial (http://web.stanford.edu/class/cs193e/Downloads/CocoaBindingsTutorial.pdf), and (although it’s referring to a much older version of IB) I think I have done what they do. Can anyone suggest what I may have omitted to do here, or why my approach is wrong? Thanks for any advice. Cheers Jonny. [*] One slight glitch - if I add an object to the NSMutableArray then it does not immediately show up in the table, I have to call will/didChangeValueForKey on the property that returns the array. I don’t know if that is expected behaviour (maybe I should be adding via the array controller somehow?). This is not a problem, but I mention it for completeness, just in case it’s indicative of something funny that is going on that I don’t fully appreciate. ___ 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 to selection of NSArrayController
Ah brilliant, that’s fixed it - thanks very much! Makes sense in retrospect that I would have to do that, but hadn’t crossed my mind at the time. Cheers Jonny On 23 Sep 2014, at 17:26, Marek Hrušovský xhrus...@gmail.com wrote: This sounds like that selection from nstableview is not properly linked. Make sure that selectionIndex (or something similar) from table is linked to arraycontroller On Tue, Sep 23, 2014 at 6:15 PM, Jonathan Taylor jonathan.tay...@glasgow.ac.uk wrote: Hi all, I feel this should be a very simple question, but I am struggling with it - the tutorials and online info I can find is either 5 years out of date or seem to imply that I am doing everything right! In my code I have an NSMutableArray of “message” objects, each with a number of properties defined on them. In the GUI this is wired up to a table view, via an NSArrayController. That all seems to work fine, and the object properties are listed in the table[*]. Underneath the table I want to display some more detailed information about the currently-selected object in the table. I would have thought that I could do this just by binding the relevant NSTextField to MessageArray.selection.myExtendedInformationProperty. This works up to a point, in that I do see text appearing in the text field. However it does not update when the selection in the table view changes, which is what I had intended to happen. This is basically what happens on p18 of this tutorial (http://web.stanford.edu/class/cs193e/Downloads/CocoaBindingsTutorial.pdf), and (although it’s referring to a much older version of IB) I think I have done what they do. Can anyone suggest what I may have omitted to do here, or why my approach is wrong? Thanks for any advice. Cheers Jonny. [*] One slight glitch - if I add an object to the NSMutableArray then it does not immediately show up in the table, I have to call will/didChangeValueForKey on the property that returns the array. I don’t know if that is expected behaviour (maybe I should be adding via the array controller somehow?). This is not a problem, but I mention it for completeness, just in case it’s indicative of something funny that is going on that I don’t fully appreciate. ___ 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/xhruso00%40gmail.com This email sent to xhrus...@gmail.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 to selection of NSArrayController
Thankyou both for your advice - it's good to have you set me right on that one. Fortunately mine is a relatively uncomplicated case, and so [NSArrayController add/removeObject:] should do the job nicely It feels a bit odd doing it that way, just because it makes the NSArray almost redundant in the whole thing - it's declared as a backing store, but this way I don't actually end up accessing it for anything. There's a rather long and redundant-seeming chain running from NSArray instance variable - property - binding - NSArrayController - IBOutlet - instance variable that I actually manipulate. Oh well, if that's the way it's meant to be... On 23 Sep 2014, at 19:57, Quincey Morris quinceymor...@rivergatesoftware.com wrote: On Sep 23, 2014, at 11:36 , Lee Ann Rucker lruc...@vmware.com wrote: On Sep 23, 2014, at 9:15 AM, Jonathan Taylor jonathan.tay...@glasgow.ac.uk wrote: [*] One slight glitch - if I add an object to the NSMutableArray then it does not immediately show up in the table, I have to call will/didChangeValueForKey on the property that returns the array. I don’t know if that is expected behaviour (maybe I should be adding via the array controller somehow?). This is not a problem, but I mention it for completeness, just in case it’s indicative of something funny that is going on that I don’t fully appreciate. Yes, it’s complicated. The ArrayController doesn’t know about changes that are made directly to the NSMutableArray. You can use [NSArrayController addObject:] for simple cases, or spend a lot of time with the KVC programming guide, especially “Collection accessor patterns for to-many properties”. In fact, Lee Ann is being a little bit kind here, because Jonny really is Doing It Wrong™. Because the UI is using bindings, it is *necessary* to update the array KVO-compliantly. Simply adding objects to the NSMutableArray isn’t KVO-compliant, hence the lack of automatic updating of the UI. The underlying problem is in thinking of the data (that is, the “M” in MVC) as an array instead of a indexed to-many property. When you make that conceptual change, then, yes, you end up in a deep relationship with the KVC programming guide. There is** a quick and dirty way of fixing this, though, without cracking open any programming guides. Anywhere that you update the NSMutableArray (either by referencing its instance variable “myArray” or “_myArray”, or a property “someObject.myArray that provides access to that instance variable), you can use a mutable proxy instead. For example, in the class that has the array, instead of: [_myArray addObject: something]; or: [self.myArray addObject: something]; you would write: [[self mutableArrayValueForKey: @“myArray”] addObject: something]; and you should magically see the updates start working. But the KVC programming guide is a better bet for a long-term relationship. ** Subject to the proviso that I’m just writing this, not doing it ATM, so I may have missed something. ___ 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
NSPopupButton, bindings, and item state
After being impressed with bindings for an NSTableView, I’m looking at what I can do for a standalone NSPopupButton, in the hope of reducing the amount of glue code I have. The button isn’t just a simple one though, I need to: - Include separator items - Disable (grey out) some items - Select multiple items (it’s configured as a pull-down menu) It’s not obvious to me that there’s a way of doing any of those things with bindings (though the multiple-selected-items might work somehow through the array controller). Can anyone advise on whether there is any hope for this approach, or do I have to accept that this is more than the bindings are intended to help with? Thanks for any suggestions Jonny ___ 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: NSPopupButton, bindings, and item state
After being impressed with bindings for an NSTableView, I’m looking at what I can do for a standalone NSPopupButton, in the hope of reducing the amount of glue code I have. The button isn’t just a simple one though, I need to: - Include separator items - Disable (grey out) some items - Select multiple items (it’s configured as a pull-down menu) It’s not obvious to me that there’s a way of doing any of those things with bindings (though the multiple-selected-items might work somehow through the array controller). Can anyone advise on whether there is any hope for this approach, or do I have to accept that this is more than the bindings are intended to help with? Short answer, yes. With some hackery you could get separator items, but the multiple checked state will likely require as much work as your glue code. So I wold say the best approaches are a 50/50 between bindings and glue. That is, you could use bindings for content, but manually handle state, or use bindings for state, and manually handle content. Doing both is probably an exercise in futility. Thanks for confirming! Out of interest, could you describe the hackery you have in mind for separators? It might still be helpful to bind the menu item titles to an array. As for manually handing state (if I were to use bindings for content), would the NSMenuDelegate method menu:updateItem:atIndex:shouldCancel: be the appropriate place to determine which items are checked, enabled, etc? In my all-manual version, I keep track of when the user checks/unchecks individual items through an action on the NSMenuItem. I'm going to have to do something else if the item list is bound to an array - any suggestions about the most appropriate place to identify when the selection changes? ___ 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: NSMenu in NSTableView column
I would create a class, say, SignalChannel, with name (for description, but we may not ant to use description for obvious reasons...) and channelID properties. I would then populate the NSPopupButtonCell with SignalChannel objects. This will abstract the model from the view, which is better form anyway. Ah, I've worked out the underlying problem I've been having. I had been trying things along these lines and completely failing to get the popup menu to populate correctly. It was working for a standalone popup but not within the table, and I was assuming I was doing something wrong and/or it was more complex than I realised, and had basically decided not to continue stumbling around trying to make it work. Then I found this: http://stackoverflow.com/questions/14708947/nspopupbutton-in-view-based-nstableview-getting-bindings-to-work which describes what seems to be a bug in the implementation, along with the workaround (binding to an outlet property on the file's owner, rather than directly to the array controller). Weird. ___ 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: NSMenu in NSTableView column
Ah, I've worked out the underlying problem I've been having. I had been trying things along these lines and completely failing to get the popup menu to populate correctly. It was working for a standalone popup but not within the table, and I was assuming I was doing something wrong and/or it was more complex than I realised, and had basically decided not to continue stumbling around trying to make it work. Then I found this: http://stackoverflow.com/questions/14708947/nspopupbutton-in-view-based-nstableview-getting-bindings-to-work which describes what seems to be a bug in the implementation, along with the workaround (binding to an outlet property on the file's owner, rather than directly to the array controller). Weird. That link refers to a view-based table view, which is a different animal altogether. Is your table view cell or view based? It makes a big difference... As it stands right now, it's view based (I switched it in InterfaceBuilder). Things seem to be working fine with that workaround. I started writing a long email to the list on the question of view- vs cell-based tables, but as is often the case, in the course of writing it I worked out the answer to my particular question at the time. I ended up with view based because Apple give clear instructions for how to bind things for them in Table View Programming Guide for Mac. Their advice for cell-based tables is rather unhelpful, just saying that it's very different and you should configure the column’s cell’s bindings. Well thanks Apple! Their instructions for view-based tables were clear, so I went with that. ___ 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
NSMenu in NSTableView column
Hi all, I am trying to implement a popup menu in an NSTableView column. I seem to have the bindings all set up so that the values in my NSArray are updated according to the options the user selects in the table. However, I would like to have some way of accessing the tag on the menu item that was selected for each row. I thought I could wire up an outlet to the NSMenu object attached to the table column, but when I later attempt to access the relevant menu item in the menu (in order to look up its tag), I get the following runtime error: -[NSMenu itemAtIndex:]: message sent to deallocated instance I do not encounter this error if I bind to a standalone popup menu, so I don't think I'm doing anything wildly stupid here. I can imagine that within the table the popup menu objects are being dynamically allocated, so the outlet plan isn't working out. My question then is how should I access the tags in the popup menu in order to work out which tag corresponds to the selected item in each row? Thanks for any suggestions Jonny ___ 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: NSMenu in NSTableView column
My question then is how should I access the tags in the popup menu in order to work out which tag corresponds to the selected item in each row? If I understand your setup correctly, the most direct route is to set an action on each menu item. Ah ok, I've revisited that and got it to work. I'd tried it before and it had had no effect; I'd assumed that was something else that just didn't work with tables. However I've now spotted the compile-time warning about only sending actions to the table view delegate, and after fixing that it works nicely. Thanks very much. Jonny ___ 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: NSMenu in NSTableView column
My question then is how should I access the tags in the popup menu in order to work out which tag corresponds to the selected item in each row? If I understand your setup correctly, the most direct route is to set an action on each menu item. Ah ok, I've revisited that and got it to work. I'd tried it before and it had had no effect; I'd assumed that was something else that just didn't work with tables. However I've now spotted the compile-time warning about only sending actions to the table view delegate, and after fixing that it works nicely. Thanks very much. Jonny Actually, I'm not sure that solves my problem as easily as I thought. I'll just restate what I'm trying to achieve to make sure I'm being clear, and then explain the difficulty I'm having in making it work. Each menu item string is a user-readable description of a signal channel, each is associated with a numerical channel ID. However there isn't a natural and obvious relationship between the index of the menu item and the channel ID. It seems sensible to me to have the menu item strings defined in the same place as the numerical IDs. I can imagine two ways of doing this: 1. Define the menu item strings in InterfaceBuilder as menu items, and give each one a tag representing the channel ID. This is what I have been trying to do, but I can't work out how my code should identify the tag associated with the menu item index (which is what I get in my NSArray representing the current state of the table). I can put an action on the menu item, but at the time that is called I don't know which row's menu has just been selected. Also (rather unexpectedly), putting an action on the menu item seems to prevent the selected index binding of the popup cell from being updated. 2. Define the menu item strings and associated channel IDs in my code, and use bindings to populate the menu items. I did try that, but haven't managed to get my strings showing up in the menu. Can anyone recommend clear instructions for making that work? I think I maybe don't properly understand the difference between content values and content, and what exactly they need to be bound to... Any thoughts about how to make either of these work? Cheers Jonny ___ 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
Contribute some dictionary keys with registerDefaults
I currently have a plist which contains some configuration values; at start of day I use the following call to make certain factory settings available to the application through NSUserDefaults: [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithContentsOfFile:configPath]]; This works fine with single-object keys. i.e. I can include a key of type Number in the plist file, and it will be made available in the same way as other user defaults. However some of my user defaults are organised within a dictionary (e.g. there is a dictionary for each separate camera connected to the system, tracking user-controllable defaults such as chosen framerate). I would like a way to contribute factory settings from my plist for some of those key values. However if I include a dictionary in my plist, and separately call [[NSUserDefaults standardUserDefaults] setObject:aDictionary forDefault:@my_camera_key]; then this dictionary object fully overrides the entire dictionary object that I supplied for my_camera_key in the plist. I had thought there was an outside chance that it would effectively merge the two dictionaries together, looking for a specific key first in the dictionary object in the user-specified defaults and then falling back to the dictionary object I supplied through registerDefaults. This does not appear to be the case though. Not sure if this makes sense - perhaps an example will help. plist supplied to registerDefaults contains: my_camera_key dictionary my_camera_key.key1 = 4 my_camera_key.key2 = 5 dictionary passed to setObject:forDefault:@my_camera_key contains: key1=7 key3=1 I had vaguely hoped that if I then called [[NSUserDefaults standardUserDefaults] objectForKey:@my_camera_key] then I might get back a dictionary containing three objects: key1=7 key2=5 key3=1 Can anyone suggest how I might achieve what I am trying to do here? (Or suggest a better mechanism of doing what I want to do, i.e. maintain some sort of hierarchy to my defaults, but also be able to supply factory settings for objects below the top level of the hierarchy? Thanks for any suggestions Jonny ___ 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
Color closest to color
Hi all, Is there a way of identifying the closest match to a given NSColor, out of a list of possible colors to match? The user could have selected any color using the color picker, but I would like to know whether it is approximately red, green, blue or white. Of course, it might be e.g. magenta, and not really map well onto one of those four, but I would still be interested in knowing the best guess. It struck me that there might be an API for that, but I couldn't immediately find one. I could probably come up with a way of doing this myself, but thought I'd see if there was anything out there already. Cheers Jonny. ___ 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: Color closest to color
Thanks everyone. I had thought there might be a pre-existing API that would do this (I was half expecting to find a method defined for the NSColorList class...), but I will implement the euclidean distance test myself... Cheers Jonny. On 17 Jun 2014, at 12:43, Maxthon Chan xcvi...@me.com wrote: One easy-to-implement method: colour cube. Define a colour using its RGB values as a 3-tuple (r, g, b) and standard colours (ri, gi, bi) (where i = 0..n).The square distance between the given colour and a standard colour is (ri-r)^2+(gi-g)^2+(bi-b)^2. You can calculate square distances between the given colour and each of the standard colours, and the one with the minimal squared distance is the best match. Better methods may exist, consult a book on computer vision or fine arts maybe? On Jun 17, 2014, at 18:52, Jonathan Taylor jonathan.tay...@glasgow.ac.uk wrote: Hi all, Is there a way of identifying the closest match to a given NSColor, out of a list of possible colors to match? The user could have selected any color using the color picker, but I would like to know whether it is approximately red, green, blue or white. Of course, it might be e.g. magenta, and not really map well onto one of those four, but I would still be interested in knowing the best guess. It struck me that there might be an API for that, but I couldn't immediately find one. I could probably come up with a way of doing this myself, but thought I'd see if there was anything out there already. Cheers Jonny. ___ 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/xcvista%40me.com This email sent to xcvi...@me.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: GCD killed my performance
Have you looked at the output from System Trace on both systems? I often find that to be informative. That might or might not be the way to tell, but have you considered that the very different CPU characteristics might mean that the actual timing and pattern of database commands is different on the iPhone, resulting in e.g. a different level of contention for the queues? Suppose dispatch_sync is fast on an empty queue but has additional overhead on a full queue - resulting in different performance on one platform to another? On 25 Apr 2014, at 04:42, cocoa-dev-requ...@lists.apple.com wrote: I’m writing an Objective-C API around a database library, and trying to add some optimizations. There’s a lot of room for parallelizing, since tasks like indexing involve a combination of I/O-bound and CPU-bound operations. As a first step, I made my API thread-safe by creating a dispatch queue and wrapping the C database calls in dispatch_sync blocks. Then I did some reorganization of the code so different parts run on different queues, allowing I/O and computation to run in parallel. On my MacBook Pro this gave me a nice speedup of 50% or more. But when I tested the code on my iPhone 5 today, I found performance had dropped by about a third. Profiling shows that most of the time is being spent in thread/queue management or Objective-C refcount bookkeeping. It looks as though adding GCD introduced a lot of CPU overhead, and the two cores on my iPhone aren’t enough to make up for that, while the eight cores in my MacBook Pro make it worthwhile. I tried backing out all the restructuring of my code, so there’s no actual parallelism going on, just the dispatch_sync calls. Predictably, performance is even worse; slightly more than half as fast as without them. So, I’m pretty disappointed. I know that dispatch queues aren’t free, but I wasn’t expecting them to be this expensive! I’m not doing anything silly like wrapping dispatch_sync around trivial calls. The APIs I’m using it on do things like reading and writing values from the persistent store. I was expecting the cost of thread-safety to be lost in the noise compared to that. ___ 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
Bindings for dynamically populated menu
This must be a very basic question, but I am evidently having difficulty finding the right search terms. Can anyone point me to some sample code that will show how to implement a menu whose items are populated at runtime? I would have expected to be able to bind a menu object to an NSArray consisting of a series of menu item titles, but IB doesn't seem to offer any suitable binding names. Is there a way of doing that, or if not can anybody point me to some sample code that will show me what methods I need to override in my own subclass of NSMenu (if that's what I need to do). The menu will contain the names of however many suitable devices are connected to the machine at the time. Thanks in advance Jonny ___ 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: Bindings for dynamically populated menu
On 7 Apr 2014, at 11:25, Keith J. Schultz wrote: Hi Jonny, try Menu items on the fly! To my knowledge you can not use IB! Thanks for your reply keith. I hadn't tried those search terms, but no that didn't get me anything relevant either. All I could find was one old thread in which various conflicting advice is given and it is reported that one promising approach results in crashes: http://www.cocoabuilder.com/archive/cocoa/29044-cocoa-building-menu-on-the-fly.html However, more blind searching around has led me to NSMenuDelegate, which looks to me what I want... ___ 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: Window controllers and memory leaks
Thanks Kyle and Jerry. It feels a bit strange to be adding extra glue code to track otherwise-completely-autonomous windows (and controllers), but that has certainly done the trick. I found the static analyzer a bit odd to get used to - it sometimes gives purportedly very detailed explanations of its logic that actually seem to miss out the key non-obvious step (e.g. obscure code path accidentally returning nil from a constructor). Once I'd got the hang of it, though, it was a great tool. Cheers Jonny. ___ 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
Window controllers and memory leaks
This must be an incredibly basic question, but I haven't found an answer I'm convinced by (apologies if I have missed something on the list). My question relates to window controllers, and how ownership, retain/release etc should be managed in order to (a) be correct and (b) satisfy the static analyzer. This has come up because it's only now that I have migrated my codebase to be compatible with the latest version of xcode that I have been able to run the static analyzer over it and examine the results. I want to allocate a window + controller, and I want it to live until the user closes the GUI window, at which point I want it to disappear and clean up after itself. I believe that the following code does not leak memory and behaves as intended. @interface MyWindowController : NSWindowController NSWindowDelegate { } @end @implementation MyWindowController -(id)init { if (!(self = [self initWithWindowNibName:@MyNib])) return nil; // Window will release self when closed, so we need to retain an extra time here [self retain]; return self; } -(void)dealloc { printf(Deallocated\n); [super dealloc]; } -(void)windowWillClose:(NSNotification*)note { [self autorelease]; } @end void TestWindowController(void) { MyWindowController *myWindowController = [[MyWindowController alloc] init]; [myWindowController.window makeKeyAndOrderFront:nil]; // We own a reference to myWindow since we allocated it, // but we have now finished all the setup we want to do // and are relinquishing control of the window object, // releasing it into the big wide world to live or die // as it may. [myWindowController release]; } However the static analyzer complains that there is a potential leak of myWindowController, because it recognises that it has a retain count of 2 when it returns from the init method. (The same applies if I don't retain in init and don't release in TestWindowController). It strikes me that this would be quite a common pattern. I appreciate that the static analyzer doesn't *know* whether there's a leak or not, but if I am indeed correctly following a common pattern then I would have expected the analyzer to understand what is going on. My question then is whether I am doing things in an unconventional way here, and/or whether there is something I could change that would help the analyzer understand what is going on. Many thanks Jonny. ___ 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
Debugging kCGErrorIllegalArgument: CGSUnionRegionWithRect : Invalid region
Can anybody help me diagnose an error that I see intermittently? The errors are as follows: Thu Sep 5 10:11:11 Jonathan-Taylors-Mac-Pro.local Spim GUI[34152] Error: kCGErrorIllegalArgument: CGSUnionRegionWithRect : Invalid region Thu Sep 5 10:11:11 Jonathan-Taylors-Mac-Pro.local Spim GUI[34152] Error: kCGErrorFailure: Set a breakpoint @ CGErrorBreakpoint() to catch errors as they are logged. (gdb) continue Thu Sep 5 10:11:17 Jonathan-Taylors-Mac-Pro.local Spim GUI[34152] Error: kCGErrorIllegalArgument: CGSGetRegionBounds : Invalid region Searching for those terms finds suggestions that this may be associated with updating progress bars from a secondary thread. I still see the error even after removing the only progress bar from my program; I don't know whether the cause is something genuinely associated with progress bars, or whether it's just that it's easy to slip up and update them from a secondary thread, triggering this error. The error is very intermittent which makes narrowing it down hard, and setting the breakpoint as advised hasn't helped me since there isn't anything of mine in the call stack when the condition is encountered: #0 0x97a7610a in CGErrorBreakpoint #1 0x97b0b9e0 in CGSGlobalErrorv #2 0x978e96d5 in CGSUnionRegionWithRect #3 0x984ea84c in -[NSRegion addRegion:] #4 0x984ea69d in -[NSWindow _setNeedsDisplayInRegion:] #5 0x9843ae86 in -[NSWindow _absorbDeferredNeedsDisplayRegion] #6 0x98439a54 in -[NSView _sendViewWillDrawInRect:clipRootView:suppressRecursion:] #7 0x9839c80e in -[NSView displayIfNeeded] #8 0x98365b64 in -[NSWindow displayIfNeeded] #9 0x9839707e in _handleWindowNeedsDisplay #10 0x94f04dd2 in __CFRunLoopDoObservers #11 0x94ec0ced in __CFRunLoopRun #12 0x94ec03c4 in CFRunLoopRunSpecific #13 0x94ec01f1 in CFRunLoopRunInMode #14 0x92e8ce04 in RunCurrentEventLoopInMode #15 0x92e8cbb9 in ReceiveNextEventCommon #16 0x92e8ca3e in BlockUntilNextEventMatchingListInMode #17 0x9836d595 in _DPSNextEvent #18 0x9836cdd6 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] #19 0x9832f1f3 in -[NSApplication run] #20 0x98327289 in NSApplicationMain #21 0x2b69 in start at vector.tcc:244 Can anyone advise on anything I can do to help diagnose this? Even something that made it happen much more frequently would be some help, as I might then have more of a chance of narrowing down the cause by disabling chunks of code. Cheers Jonny ___ 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: Debugging kCGErrorIllegalArgument: CGSUnionRegionWithRect : Invalid region
You can't do any UI-related updates from a secondary thread, you must ask the main thread to do it. It might not be progress bars but anything at all that's being drawn from a secondary thread. The error itself could indicate that an internal data structure was used or updated by another thread while in an inconsistent state. Yes, I understand that. I am not aware of doing any drawing from secondary threads, although evidently it appears that somewhere in the program this is happening. My question is whether I can do anything to help track down the problem, because right now I am limited to code reading and/or the very slow process of disabling sections of code (slow because it's an intermittent problem and each time I would need to run for long enough that I can be reasonably sure I would have hit the error if I was going to...). ___ 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: Threadsafe copy of objective c object
On 4 Sep 2013, at 16:46, Marcel Weiher wrote: Unless there is some dire reason not to do this, I would make a copy on the main thread every time the UI changes, and stash that copy somewhere the worker thread can access it easily. That's a really good plan, I realised that last night. I had been stuck thinking about kind of the opposite approach (make a copy on each invocation of the processing algorithm), but this makes a lot of sense. How does this sound: When the UI leads to changes in the (mutable) primary object I'll make a copy stored in an immutable shadow object (from the main thread). Whenever the algorithm is invoked (from a secondary thread in response to receipt of a frame) I retain the immutable shadow object and pass this pointer to the algorithm. Sounds pretty good to me. I’d probably stash it in an instance variable. In a sense, this is a variant of the immutability that Ian and Jens suggested: create a copy that you won’t mutate. OK, thanks everyone for your input on this one. I've got something I'm fairly happy with now, which is working according to plan. I was a bit surprised at how much glue I ended up having to put together to make it work though. Maybe that's just the nature of the thing, but if anybody was interested enough to critique the code that I've come up with (on or off list) then I'd be very grateful to hear any comments. https://docs.google.com/file/d/0Bye8FKbpg3dYa1R2Z1hPWERmcjQ/edit Cheers Jonny. ___ 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: Debugging kCGErrorIllegalArgument: CGSUnionRegionWithRect : Invalid region
Do you have any secondary threads? I assume you do. Indeed! Any code that touches a view, no matter how indirectly, could be the culprit. Bear in mind that sending any message to any view (controls, etc) might invoke -setNeedsDisplay: which in turn could be the trigger for the problem. Try setting a breakpoint on -setNeedsDisplay: though of course it will be hit a lot, so you might need a clever condition to avoid being overwhelmed. Even one that excludes the main thread might help, e.g. [NSThread currentThread] != [NSThread mainThread] That suggestion for a breakpoint is a great one. Sadly the condition you quoted doesn't seem to be parsed correctly by the debugger, even with casting. Even just po (NSThread*)[NSThread currentThread] fails on my machine. Fortunately, though, there were only a couple of dozen hits on the breakpoint per iteration of the code, and sure enough it immediately pinpointed a case where I was erroneously calling willChangeValueForKey from a secondary thread, which was causing a GUI update as a side-effect. Cheers Jonny. ___ 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: Threadsafe copy of objective c object
Thanks to everyone who has chimed in on this one - you've all been really helpful. Looks like some conclusions are emerging; some selected replies below. On 3 Sep 2013, at 20:21, Tom Davie tom.da...@gmail.com wrote: Remove the mutation methods. Make your object immutable, the referential transparency will give you “free” parallelism. If you want a mutated version of the object, create a new object. Very good suggestion, though unfortunately my use of UI bindings rather scuppers that one. Otherwise it could be an ideal solution On 3 Sep 2013, at 19:49, Marcel Weiher marcel.wei...@gmail.com wrote: What are the property parameters? A bunch of numbers, maybe some strings? Yep. Unless there is some dire reason not to do this, I would make a copy on the main thread every time the UI changes, and stash that copy somewhere the worker thread can access it easily. That's a really good plan, I realised that last night. I had been stuck thinking about kind of the opposite approach (make a copy on each invocation of the processing algorithm), but this makes a lot of sense. How does this sound: When the UI leads to changes in the (mutable) primary object I'll make a copy stored in an immutable shadow object (from the main thread). Whenever the algorithm is invoked (from a secondary thread in response to receipt of a frame) I retain the immutable shadow object and pass this pointer to the algorithm. From what Jens and others have said, it's my understanding that if the property for the (immutable) shadow object is designated atomic/retain then I wouldn't need a mutex to access it. On 3 Sep 2013, at 18:37, Jens Alfke j...@mooseyard.com wrote: This is one reason why concurrent programming often relies on immutable objects — because they can be passed around multiple threads safely. Thread-safe access to mutable objects is a real pain and it’s very easy to create subtle bugs that only show up very rarely. Wise words that I had rather lost sight of! I was too focused on incremental changes to the original (poor) design... On 3 Sep 2013, at 18:26, Kyle Sluder k...@ksluder.com wrote: One of the cardinal rules of Audio Units is Thou Shalt Not Allocate Memory On The Render Callback Thread. malloc takes a lock. Taking a lock is a great way to make you thread miss its hard-realtime constraint, which leads to glitching and potentially getting killed by the host. Yes, I learned that one the hard way a while back! ___ 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
Threadsafe copy of objective c object
This feels like it should be a very basic question, but it's not one I've managed to find an answer to - can somebody here advise? I have an objective c object which contains a number of properties that serve as parameters for an algorithm. They are bound to UI elements. I would like to take a snapshot copy of the object that will be used for one whole run of the algorithm (rather than risk parameters changing halfway through the run). i.e. I just want to do [myObject copy]. The complication is in ensuring this is threadsafe: ideally I would like to make the copy on a thread other than the main thread. My understanding is that properties themselves, even when designated atomic, are in some way not fully threadsafe, although I haven't found a clear explanation of exactly what makes them unsafe. I don't know if the 'copy' method is threadsafe or not, I am inclined to suspect not. Is there any way, then, that I can take a copy in a threadsafe manner? If necessary I can do the copy on the main thread, but I would prefer not to have to do that for timing reasons. Any suggestions? Cheers Jonny. ___ 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: Threadsafe copy of objective c object
Ah, that's a good point about implementing -copy myself. However, how would @synchronized(self){…..} help there? Surely all that would do is prevent multiple threads from calling 'copy' simultaneously - which as far as I am aware isn't something I should be worried about. My understanding is that it would have no impact on whether for example the copied object contains correct values. If it's relevant, I should add that the object's properties are all simple types (double, int, bool etc). It doesn't help that I'm not really sure what window conditions I am guarding against in my desire for thread safety, which makes my question a little vague. I guess that what I would like is the following: - [myObject copy] will not crash/raise exceptions/etc when called from a thread other than the main thread - [myObject copy] returns a copy in which all parameters are 'valid' (i.e. an individual parameter is either the 'old' or the 'new' value in the case where the object is being changed at the time of the copy) - True thread safety would require a copy that represents an instantaneous snapshot of the state of the entire object, i.e. copy not taken while object is being updated. Actually, I suspect this last condition is not a problem for my specific case, but best to be on the safe side, for several different reasons. On 3 Sep 2013, at 12:04, Graham Cox wrote: On 03/09/2013, at 12:52 PM, Jonathan Taylor jonathan.tay...@glasgow.ac.uk wrote: Is there any way, then, that I can take a copy in a threadsafe manner? If necessary I can do the copy on the main thread, but I would prefer not to have to do that for timing reasons. Any suggestions? Since the implementation of -copy is up to you, you could just put @synchronized(self){…..} around the code in that method. That implements a lock which should make the copy thread-safe. --Graham ___ 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: Threadsafe copy of objective c object
Is it possible to reverse the issue? Keep the original object (living on the main thread) untouched, make a copy for algorithm processing as an async task, then, when done, update the original object from the copy that may have been changed during async processing? Or will that cause the exact same problem in the final step? Things are simpler than that I think - the object containing the parameters won't be changed by running the algorithm. The copy that I want to take will be treated as read-only. To recap/expand: The primary instance of the object (call it MyParameters) is bound to UI elements. Changes to the UI will change the values of its properties (int/bool/double). These changes will take place on the main thread. I would like to be able to take a copy of MyParameters from a thread that is not the main thread, and have that copy be a non-corrupted snapshot of the primary instance of MyParameters. The copy will not be altered; no changes need to be propagated back to the primary instance. Indeed, the motivation behind my question is the *requirement* that this copy does not change in any way (despite the primary instance possibly changing). I am not sure how to do this in a fully correct manner. One might naively expect that designating properties as atomic could be sufficient. However I have read that even atomic properties are not threadsafe - although I was not able to establish the reason for this statement. Perhaps that statement only applies to more complex objects, in which case it may be I am worrying over nothing. Op 3 sep. 2013 om 13:16 heeft Lasse Jansen la...@lasselog.com het volgende geschreven: Since the implementation of -copy is up to you, you could just put @synchronized(self){…..} around the code in that method. That implements a lock which should make the copy thread-safe. No, it wouldn't. It would only ensure that two calls to copy are executed sequentially. You would need to add @synchronized(self) {…} to all other methods that modify the object too to ensure that the object isn't changed during a copy. Lasse Sent with Unibox ___ 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/diederik%40tenhorses.com This email sent to diede...@tenhorses.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: Threadsafe copy of objective c object
All sounds nice, except for the fact that the parameters are being changed behind the scenes via the binding system. So I think I may have to implement locking on every (explicitly implemented) get/set method. That was what I had been rather hoping to avoid, but it sounds from what people are saying as if that's what I may have to do... On 3 Sep 2013, at 13:54, Robert Vojta wrote: On Tue, Sep 3, 2013 at 2:39 PM, Jonathan Taylor jonathan.tay...@glasgow.ac.uk wrote: The primary instance of the object (call it MyParameters) is bound to UI elements. Changes to the UI will change the values of its properties (int/bool/double). These changes will take place on the main thread. 1. Create MyParameters instance on some object on the main thread and call it mainParameters for example. 2. All values are UI related, so, fill them on the main thread. But lock your mainParameters object before. So, on the main thread do this ... @synchronized( myObjectHoldingMyParameters.mainParameters ) { myObjectHoldingMyParameters.mainParameters.X = X; ... } 3. When you do want a copy on any other thread, do this ... MyParamaters *paramsCopy; @synchronized( myObjectHoldingMyParameters.mainParameters ) { paramsCopy = [myObjectHoldingMyParameters.mainParameters copy]; } ... and implement deep copy without locking. It's done via @synchronized. ___ 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: Threadsafe copy of objective c object
Ah. In my original email I didn't explain *why* it is that ideally I would like to make the copy on a thread other than the main thread. The algorithm is doing real-time video processing, and I very much want to avoid holding up anything in that code path by synchronizing with the main queue. Past experience has shown that that does lead to glitches I am keen to avoid. So, while I'm a big fan of such constructions, I'm deliberately trying to avoid that here. Serializing access to MyParameters will work, it's just a shame that there isn't such a tidy way of achieving that... On 3 Sep 2013, at 14:18, Robert Vojta wrote: Then this should be enough ... - (MyParameters *)copyParameters { __block MyParameters *parameters; dispatch_sync( dispatch_get_main_queue(), ^{ parameters = [myObjectHoldingParameters.parameters copy]; }); return parameters; } ... if all your parameters object properties are set on the main thread only. ___ 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: Memory not being released in a timely manner
Thanks for your comments Ken. It was really good to learn about how to use heapshots effectively, that's definitely something I'm going to use again in future. In this case it did provide ~some~ more information on what is going on. Just to be clear, the problem is now solved by wrapping the correct bit of code in an explicit autorelease pool, but I'm still very interested in understanding what's going on and why Allocations is not reporting large chunks of memory - I still maintain that this is not happening. If I understood your reply correctly, you're saying this isn't what you would expect. The following results are with the explicit autorelease pool (bug fix for my issue) disabled so that the problem manifests itself. With the use of heapshots, it does turn out there are in fact ~small~ objects accumulating that are reported by Allocations. An example screenshot can be viewed here: https://docs.google.com/file/d/0Bye8FKbpg3dYRWF0YWo1djNmZVU/edit?usp=sharing However this is only reporting relatively small amounts of memory still outstanding from during the image processing run. The fact that there are Image/Bitmap objects in there should ring alarm bells, and watching one of those objects would have given me a very strong clue as to what was going wrong, had I done it earlier. For example: https://docs.google.com/file/d/0Bye8FKbpg3dYcnlQRWt0ZDlVdjA/edit?usp=sharing is pretty strong evidence that it's a delay in autorelease pool drain that is causing all this memory to sit around. However, if I understand you correctly, you are convinced that the (large) backing buffer for the bitmap data should be being reported by Allocations. As you can hopefully see from these screenshots, while the NS objects themselves are being reported as live, the backing memory itself really doesn't seem to be showing up in Allocations (though the VM tracker knows about it. When you wrote: So, the Allocations instrument should have been showing you those living objects. True, it couldn't show you the size of memory ultimately dependent on those objects, but that's often the case (i.e. a small object that owns a large NSData or something; Allocations would sort the NSData to the top but you'd have to hunt to find the small object that owns it). ... it seems that my observations match that in terms of the top-level objects, but there really doesn't seem to be any sign at all of the backing memory. Weird. Cheers Jonny ___ 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: Memory not being released in a timely manner
The Allocations instrument should report objects with pending autoreleases as ordinary live objects. (Note that many objects with retain count == pending autorelease count will be retained again before the autorelease pool pops.) In OS X 10.8 and iOS 6 simulator, you can set environment variable OBJC_PRINT_POOL_HIGHWATER=YES to get debugging logs of the autorelease pool high-water mark on each thread. This can detect code that accumulates lots of autorelease garbage without spinning any pools. (The high-water mark is not checked until the pool is popped, so you'd have to actually finish the work to see the result.) Thanks for your comments Greg, very interesting. Unfortunately (in a sense!) the problem doesn't seem to happen on 10.8, so I can't reproduce the problem and get those debug logs. The Allocations instrument should report objects with pending autoreleases as ordinary live objects Do you happen to know if that's true of Allocations on 10.6? Is that definitely true for objects that have actually passed out of scope, and it would therefore be forbidden to re-retain them (if you know what I mean), but which haven't actually been freed behind the scenes? I'm not seeing Allocations report large amounts of memory. I assume that it should be reporting anything that is present within my 32-bit address space (i.e. I assume there isn't any way that external libraries could allocate memory that is in some way hidden from Allocations)? If that is the case, I suppose the only other possibility I can think of is that I am fragmenting the address space to such an extent that there is no way of allocating any further buffers (size of order 1MB). Currently my understanding of the problem is pretty much limited to: - Allocations claims only 300MB allocated memory - 1.2MB buffer cannot be allocated (insufficient memory) - Occurs when program is in background, and tickling autorelease pools at 1 second intervals makes the problem go away. - Occurs on 10.6, not on 10.8 I do have a solution in the form of the tickling, but I'd be very interested if you had any suggestions on ways I could dig further into the underlying cause. Cheers Jonny ___ 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: Memory not being released in a timely manner
It smells like you're doing a lot of processing with temporary objects, in a loop, without bracketing the loop body in @autoreleasepool{}, but I remember you saying you're not. Oh dear. Oh dear. You are right. I know this is what everybody has been telling me all along. I have a tiny one-line GCD block that is re-posted back onto the main event loop (for thread safety reasons), which I had overlooked. It was setting off a chain reaction of binding notifications etc that resulted in the image as displayed in the GUI being updated. An autoreleased image buffer involved in this wasn't being caught by an explicit pool, and so was falling foul of the problem described by Jeff Johnson whereby autoreleased objects weren't being cleaned up in a timely manner. So, wrapping that single line of code in an autorelease pool has fixed it. I'm so sorry for taxing everyone's patience on this one! Your suggestion of the VM Tracker instrument (which I had not spotted before) did bring up some interesting results though. These autoreleased image buffers that were causing the problem are definitely NOT reported at all by Allocations (live bytes stays stable at 250MB), but they do show up under VM Tracker as CG image and CG raster data - although I don't think there's a way of getting any further details about the buffers they provide the backing for? I do think it's interesting though (and a bit worrying) that the only way I could pinpoint the actual problem was by reading through the relevant bits of my code over and over - I wasn't able to glean any info from Instruments that really narrowed things down, other than to confirm that there were definitely image buffers accumulating somewhere. Jonny. ___ 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: Memory not being released in a timely manner
Thankyou all for your replies. A few responses - On 4 Jun 2013, at 16:30, Jeff Johnson wrote: We've run into this issue in a number of apps. As a workaround, we add a timer to the main thread and have it fire periodically. The timer's action method does the following: Thanks again! I've implemented your code and that has fixed my problem - great news. On 4 Jun 2013, at 18:33, Jens Alfke wrote: I don’t know if ObjectAlloc is supported anymore; you should be using Instruments. It’s been a long time since I used that app, so I don’t know if it reports all heap allocations or just Obj-C objects. The problem is that a small object (like an NSImageRep) can be hanging onto huge memory buffers for pixels. Apologies, I meant the Allocations tool within Instruments. [Incidentally, in my install ObjectAlloc just launches Instruments/Allocations] As far as I can see, the Allocations tool does not report memory that is pending release from an autorelease pool. It would be interesting to know if there was a way of monitoring that. Re your suggestion about wrapping code with my own autorelease pools, I have done so but I am pretty sure the movie generation APIs that I am using launch their own threads, ones that I don't have control over. Without being able to see exactly what allocations are still pending release, I can't be sure, but I am as certain as I can be that that's where the memory-pending-autorelease must be accumulating. The problem seems to be that, even though ObjectAlloc thinks the memory has been released, it is not actually being properly freed up until some time later. The memory usage as reported in Activity Monitor climbs higher and higher until, if left unattended, there is apparently no more memory available. There are a lot of different numbers measuring different kinds of memory usage, and not all of them are relevant to this. What specific value in Activity Monitor are you talking about? The most relevant one is Private Mem (RPRVT). Yep, that's the one. (I was trying to keep my original email reasonably concise!) Cheers Jonny. ___ 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
Memory not being released in a timely manner
Hi all, Can anybody advise what tools I should be using to debug a particular out of memory condition - and maybe even how I can fix it? The error that I ultimately encounter (in a 32-bit application on Snow Leopard) is: 2013-06-03 15:44:30.271 MyApplication[25115:a0f] NSImage: Insufficient memory to allocate pixel data buffer of 1228800 bytes However as I'll explain I don't feel that I am doing anything that should result in running out of memory. The program loads and processes a large number (~2000) image files, and I believe that I am disposing of memory and draining autorelease pools correctly. Running the program under ObjectAlloc, it never reports memory usage over 300MB. The problem seems to be that, even though ObjectAlloc thinks the memory has been released, it is not actually being properly freed up until some time later. The memory usage as reported in Activity Monitor climbs higher and higher until, if left unattended, there is apparently no more memory available. Clicking the mouse or switching applications causes an immediate and significant drop in memory usage. Thus the situation seems to be that I believe I am doing everything I can for good memory management, but the OS is not actually freeing things up for re-use. I encountered a similar problem that I asked about on here last year: http://lists.apple.com/archives/cocoa-dev/2012/Jul/msg00602.html Although in that case the eventual conclusion was that I should be using a different approach in my code, it involved the same issue of memory not being released when I would have expected it to be. In that case from last year, I was wrong to rely on it being released when I expected, but I feel that this time it should be reasonable to expect that I won't run out of memory entirely, given that I am releasing all the buffers that I am finished with and only keeping a small working set allocated! This is of course partly just speculation because ObjectAlloc isn't giving any info about this unavailable but apparently not-allocated memory. So... 1. Can anybody recommend a way of debugging this problem to get more concrete evidence for what is actually happening? 2. Assuming my interpretation is correct, can anybody suggest a solution? Many thanks Jonny ___ 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: Memory not being released in a timely manner
Hi Jeff, Thanks very much for your reply. That's brilliant. I had tried playing around with a few tricks I thought might prompt a pool drain, but to no joy. It's great to have a bit of code that will do the job for that - I'll give it a go tomorrow. Cheers Jonny On 4 Jun 2013, at 16:30, Jeff Johnson publicpost...@lapcatsoftware.com wrote: Hi Johnny. This is a long-standing problem with AppKit. According to the documentation, The Application Kit creates an autorelease pool on the main thread at the beginning of every cycle of the event loop, and drains it at the end, thereby releasing any autoreleased objects generated while processing an event. However, this is somewhat misleading. The end of the event loop cycle is immediately before the beginning. Thus, for example, if your app is in the background and not receiving events, then the autorelease pool will not be drained. That's why your memory drops significantly when you click the mouse or switch applications. We've run into this issue in a number of apps. As a workaround, we add a timer to the main thread and have it fire periodically. The timer's action method does the following: NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint modifierFlags:0 timestamp:[NSDate timeIntervalSinceReferenceDate] windowNumber:0 context:nil subtype:0 data1:0 data2:0] [NSApp postEvent:event atStart:YES]; This basically tickles the event loop and causes the autorelease pool to drain. -Jeff On Jun 3, 2013, at 10:59 AM, Jonathan Taylor jonathan.tay...@glasgow.ac.uk wrote: Hi all, Can anybody advise what tools I should be using to debug a particular out of memory condition - and maybe even how I can fix it? The error that I ultimately encounter (in a 32-bit application on Snow Leopard) is: 2013-06-03 15:44:30.271 MyApplication[25115:a0f] NSImage: Insufficient memory to allocate pixel data buffer of 1228800 bytes However as I'll explain I don't feel that I am doing anything that should result in running out of memory. The program loads and processes a large number (~2000) image files, and I believe that I am disposing of memory and draining autorelease pools correctly. Running the program under ObjectAlloc, it never reports memory usage over 300MB. The problem seems to be that, even though ObjectAlloc thinks the memory has been released, it is not actually being properly freed up until some time later. The memory usage as reported in Activity Monitor climbs higher and higher until, if left unattended, there is apparently no more memory available. Clicking the mouse or switching applications causes an immediate and significant drop in memory usage. Thus the situation seems to be that I believe I am doing everything I can for good memory management, but the OS is not actually freeing things up for re-use. I encountered a similar problem that I asked about on here last year: http://lists.apple.com/archives/cocoa-dev/2012/Jul/msg00602.html Although in that case the eventual conclusion was that I should be using a different approach in my code, it involved the same issue of memory not being released when I would have expected it to be. In that case from last year, I was wrong to rely on it being released when I expected, but I feel that this time it should be reasonable to expect that I won't run out of memory entirely, given that I am releasing all the buffers that I am finished with and only keeping a small working set allocated! This is of course partly just speculation because ObjectAlloc isn't giving any info about this unavailable but apparently not-allocated memory. So... 1. Can anybody recommend a way of debugging this problem to get more concrete evidence for what is actually happening? 2. Assuming my interpretation is correct, can anybody suggest a solution? Many thanks Jonny ___ 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: NSAutounbinder not releasing my object in a timely manner
Thankyou both for your very helpful replies. The dispatch group approach sounds like a nice one - especially using dispatch_group_notify, which I had somehow overlooked. Thanks also Ken for your detailed reply to my ramblings, that was very useful for getting my understanding straightened out. Jonny. ___ 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: NSAutounbinder not releasing my object in a timely manner
this nasty NSAutounbinder thingy then jumps in and re-retains it in some evil under-the-covers voodoo to do with avoiding retain cycles (as I understand it). Unfortunately the balancing autorelease only occurs 16 seconds later when I move the mouse! While not catastrophic this is pretty annoying and looks rather embarrassing. It's not embarrassing unless your users are running your app in a debugger. Sorry, you've lost me there. Are you saying this will not occur if I am running standalone rather than under XCode? (Unfortunately I don't have the code in front of me to try this out). If that is the case then that's good - if frustrating - news. Is this a known issue then? I was working on the assumption that I was doing something obscurely wrong, or at least non-standard somewhere to trigger this from happening. Or are you saying you only see the NSAutounbinder stuff in the debugger? If so then - sure, but it's the fact that the progress bar is just sitting there until I move the mouse that alarms me. Are you saying you're relying on an object being deallocated to change your GUI? You shouldn't be. If you want to close or hide a window, send it a -close or -orderOut: message. If you want to remove or hide a view, remove it from the view hierarchy or send it -setHidden:YES. If its hidden binding is bound to a model or controller property, set that property (on the main thread). Right, that makes a lot of sense. I can understand the principle of not relying on the dealloc for that sort of thing and on first reading that made complete sense. However, I have now tracked down/remembered the piece of code that was my motivation for taking the approach I did. As always, it turns out the real question is probably not quite the one I originally asked! Can I get your opinion on this workflow? This is how I had previously done things: - User requests batch processing of data within a folder tree, which will result in between 0 and many separate movies being generated. - Application allocates a progress tracker, subclassed from NSWindowController, in control of a window containing a progress indicator and various other feedback elements. - This is supplied to separate traversal/parsing code which identifies source data from which movies should be generated. - For each movie to be generated, the progress indicator is retained in association with a GCD block which will be executed to perform the actual work, added to a serial queue - Following tree traversal, the application releases its reservation on the progress tracker. If no movies are due to be generated, I had intended this to cause it to be deallocated, at which point I had been closing the window. If work was queued, this will in due course be executed. The current work block will take control of updating the progress tracker. When it is finished it will release its reservation of the progress tracker. Again, when all work has been completed I intended the retain count to fall to zero at which point it would be deallocated and closed. My intention with all this was to avoid the need for any information sharing between bits of code that I felt should be fairly independent. The application-level code that originally allocates the progress tracker doesn't need to care about what any more specific code wants to do with the progress tracker, it just makes it available to anything that wants to retain it for future use, and then relinquishes any further personal interest in that object. Now, your statement that [you shouldn't be] relying on an object being deallocated to change your GUI seems fair, but how would you tackle my scenario here? One possible solution would be to have an intermediary object with no gui/binding/etc of its own, which allocates and owns the progress window and is retained and released by my code as necessary, closing/releasing the window when it is deallocated. In practice, I suspect that would work because that intermediary object shouldn't get caught up in any of the deferred autoreleasing that was associated with my original problem. However I am genuinely not sure whether that is just a slightly more indirect way of violating your advice, or whether it is acceptable. I guess I am not sure whether your statement is a generic design principle or a practical rule of thumb for avoiding the sort of issue I encountered. In my mind retain/release is a way of tracking the interest that my different work packages have on the progress window. If you say you don't like my intermediary object approach then my next proposal will be that I implement a manual counter of the number of work packages outstanding... which is really just me reimplementing a parallel retain/release mechanism myself. Is *that* more acceptable, or am I again violating the spirit if not the letter of your statement? I've rambled a bit here, in my attempts to understand the
Re: GCD question
If I use this to initiate a background thread: dispatch_async(dispatch_get_global_queue(0, 0), ^{ // do some stuff [self runMyFunction]; [self runAnotherFunction]; // do some more stuff }); My question is with my sample calling runMyFunction or runAnotherFunction are they blocking? Meaning will they block the background thread until they are complete and then it will continue? Or must I put them into another kind of block so that they finish FIFO? Thanks just looking for a confirmation as I'm moving to GCD from threads... You are correct in that they are blocking if I understand you correctly. There is nothing magic about the concept of GCD blocks, they are really just anonymous functions with a slightly unusual scope. You would be equally welcome to use the alternative dispatch_async_f API, which would have exactly the same outcome (code written in Mail; not complied!): void MyDispatchFunc(void *) { // do some stuff [self runMyFunction]; [self runAnotherFunction]; // do some more stuff } void foo(void) { dispatch_async_f(dispatch_get_global_queue(0, 0), MyDispatchFunc); } I hope it is obvious from this alternative formulation that there is nothing magic going on: the API call is just scheduling a call to MyDispatchFunc at the time GCD deems appropriate. Exactly the same is true of the example you gave, it is just that you are passing a block around instead of a function pointer. Hope that helps Jonny ___ 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
NSAutounbinder not releasing my object in a timely manner
I am tearing my hair out here with yet another retain issue with the NSAutounbinder. I don't know what I am doing to keep hitting these problems, and unfortunately going back through peoples past (very helpful) replies to my questions on both this and blocks+autorelease pools has not shed any light on things for me. The situation I have is I have a sheet on a window, with the sheet containing a progress indicator (and time estimate). This has a window controller associated with it, called CocoaProgressWindow (which is also the window delegate). I release the window controller, and soon afterwards its retain count falls to zero (as it should). However, this nasty NSAutounbinder thingy then jumps in and re-retains it in some evil under-the-covers voodoo to do with avoiding retain cycles (as I understand it). Unfortunately the balancing autorelease only occurs 16 seconds later when I move the mouse! While not catastrophic this is pretty annoying and looks rather embarrassing. Can anybody suggest what might be happening here? I can only assume I am doing something wrong somewhere along the line, although I cannot imagine what it might be! I have recorded full callstacks of every time my retain/release is called: http://www.dur.ac.uk/j.m.taylor/complete-call-stack.txt a version editing out the really obvious, balanced retain/releases that I know about: http://www.dur.ac.uk/j.m.taylor/call-stack-shortened.txt and one edited down to just show the two dodgy callstacks at the end: http://www.dur.ac.uk/j.m.taylor/call-stack-shortened-2.txt In general terms, I am running some demanding work (generating a movie file) on a GCD serial thread using dispatch_async and there is then a second nested dispatch_async back onto the main queue, from which I release the window controller. It is when that block is destroyed that the final real release occurs and the NSAutounbinder stuff happens. This is under Snow Leopard, no GC or ARC. It might be relevant that I am running with Mike Ash's ZeroingWeakReference code compiled in, although the code in question here makes no use of that facility whatsoever. Can anybody speculate what my problem might be, and how I can deal with it? Many thanks Jonny ___ 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: Capturing 'self' strongly in this block is likely to lead to a retain cycle
In practice, NSOperationQueue probably releases the block when it's done with it I'm curious about your use of the word probably here. Can you explain? This is probably not what the OP had in mind, but I might mention that I've seen situations where autoreleases associated with NSOperationQueues and GCD queues have still been outstanding five minutes later under conditions of extremely high load. (My suspicion is that a mouse click or other user event causes these to be carried out, but I didn't test that one systematically). ___ 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
NSWindowController subclasses, and retain cycles
I have been battling a retain cycle for a couple of hours, assuming I am at fault, but I am starting to think there is something fishy going on. Can anybody advise? - I have a window controller subclass (and associated window) A, and a separate window controller subclass (and associated window) B. B contains a property, designated 'retain', that keeps a pointer to A. B is programatically closed first, and later on A is programatically closed - I believe that I am correctly balancing retain/release for A. - I believe I am doing the same for B. 1. If I do not set B's pointer to A, both A and B are deallocated correctly 2. If instead I set B's pointer to A, but reset it to nil just before B is closed, both A and B are deallocated correctly 3. If instead B still has a live pointer to A when B is closed, this should be autoreleased by the runtime, which it is. However, A never gets deallocated. There appears to be some weird runtime voodoo behind the scenes involving NSAutounbinder, which I think is what should ultimately be sending the final release to A. That is what sends the final release to B, but that final release for A is missing under that third scenario above. I am concerned by the following post: http://theocacao.com/document.page/18 This seems to imply there is some dodginess behind the scenes that Apple have bodged to try and make things work. The blog post is 8 years old, so I would have hoped this would be sorted by now(!), but it does sound remarkably close to my scenario here. I may have missed out some important relevant information here, so let me know if I need to be more specific about what I am doing, but can anybody suggest: - If you agree the problem is likely to be with the runtime rather than with my code - What the best workaround would be (scenario 2 above will probably do as a workaround...) - Whether the fact that I am hitting this suggests I am doing something out of the ordinary that I should probably be doing differently. Thanks for any advice Jonny ___ 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: NSWindowController subclasses, and retain cycles
On 24 May 2012, at 16:27, Kyle Sluder wrote: 1. If I do not set B's pointer to A, both A and B are deallocated correctly 2. If instead I set B's pointer to A, but reset it to nil just before B is closed, both A and B are deallocated correctly 3. If instead B still has a live pointer to A when B is closed, this should be autoreleased by the runtime, which it is. However, A never gets deallocated. If A somehow has a chain of retains that keeps B alive, #3 is wrong. Your approach with #2 seems sensible. Thankyou all three for your replies. [I am not using ARC as this must run on Snow Leopard, incidentally]. Having done some playing around with trivial test cases, it appears that I have completely misunderstood a basic concept of properties - apologies for wasting your time. I had always thought that if I declare a property as follows: @property (retain) MyProgressWindow * progressObject; ... @synthesize progressObject = _progressObject; then if that property has a non-nil value at the point that the instance is deallocated, a release would be sent. That had always struck me as the obvious behaviour, but it appears that this does not happen. I am sure there is a good reason for that! Not sure how I have managed to go this long without spotting that I am wrong here. Seems a bit of a pain to have to go through setting everything to nil in the dealloc method (which I would otherwise not have to even implement at all in many cases), but looks like that's what I need to do... Cheers Jonny ___ 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 and multithreading
It sounds, though, as if it should be ok to use observeValueForKeyPath:ofObject:change:context (which will run on the secondary thread, by the sound of it) as a way of monitoring the fact that something has changed in the state of my object. I can then use that as a single place in which I schedule a GUI update via a shadow object on the main thread. Does that sound as if it would be ok? On 23 Mar 2012, at 23:14, Dave Fernandes wrote: See the Cocoa Design Patterns doc: The Receptionist Design Pattern in Practice A KVO notification invokes the observeValueForKeyPath:ofObject:change:context: method implemented by an observer. If the change to the property occurs on a secondary thread, theobserveValueForKeyPath:ofObject:change:context: code executes on that same thread. So you shouldn't use observeValueForKeyPath:ofObject:change:context to update the GUI in this context. I don't know of any better method than what the OP suggested. Cheers, Dave On 2012-03-23, at 6:32 PM, Jan E. Schotsman wrote: Jonathan Taylor wrote: I have been struggling with a problem which I think I have eventually realised is down to me not handling multithreading issues properly. The situation is I have some computationally-demanding code that is running in a separate thread. This has input parameters and state variables associated with it. For diagnostic reasons I would like to be able to display the values of the state variables in the GUI. I had intended to do this just by binding to them. However I am getting occasional message sent to deallocated instance errors which I suspect are a symptom of the fact that I am Doing It Wrong. Further reading suggests that because of the way bindings work, modifying those state variables is leading to binding/gui type stuff happening away from the main thread, which appears not to be permitted. I use KVO for this. Have your main thread observe the state variables (declared as properties) and update the GUI in your observeValueForKeyPath:ofObject:change:context: method. I hope this is elegant enough for you ;-) Jan E. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/dave.fernandes%40utoronto.ca This email sent to dave.fernan...@utoronto.ca ___ 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 and multithreading
I have been struggling with a problem which I think I have eventually realised is down to me not handling multithreading issues properly. The situation is I have some computationally-demanding code that is running in a separate thread. This has input parameters and state variables associated with it. For diagnostic reasons I would like to be able to display the values of the state variables in the GUI. I had intended to do this just by binding to them. However I am getting occasional message sent to deallocated instance errors which I suspect are a symptom of the fact that I am Doing It Wrong. Further reading suggests that because of the way bindings work, modifying those state variables is leading to binding/gui type stuff happening away from the main thread, which appears not to be permitted. What I can't work out is whether there is a reasonably elegant and uncomplicated way of achieving what I want: the properties in question are being modified from a secondary thread, and I would like to display their values in the GUI, preferably via bindings for convenience. I could for example keep a shadow object which the GUI binds to, whose state is updated either periodically or in specific response to changes to properties in the primary object based in the secondary thread. However that strikes me as rather unwieldy and requiring a fair amount of extra code to implement correctly and efficiently. I feel there must be a better way of dealing with my problem - or maybe there isn't, and I just need to accept that bindings etc do not work well in a multithreaded environment. Does anybody have any advice? Cheers Jonny ___ 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: ObjectController preventing WindowController from releasing
Well, in this case I certainly think it would be better to bind the object controller to File's Owner.camera. Really, I wasn't so much getting at anything in particular, I just find it odd for an object controller to have a window controller as its content. I also find it odd to bind to File's Owner.self. I can't say for sure that either is the source of the problem, but they strike me as suspicious. Hmm, certainly the problem seems to have gone away if I bind to File's Owner.camera. Interesting. I guess I should take that as a sign that I am expected to separate my model and controllers properly! If your data model is within the window controller and you want a means to use -commitEditing, then you should probably make the window controller conform to NSEditor and NSEditorRegistration, just as NSController (and thus NSObjectController) does. I'll have a look at that, thanks.___ 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
ObjectController preventing window from closing
Hi all, This is probably a very basic question, but I am out of ideas and hoping someone can offer some help. I should say that I'm afraid I'm somewhat out of my depth with ObjectControllers: I added some seemingly simple bindings at the recommendation of a poster on here, and I thought I understood what it was doing, but the fact that I am now having retain issues suggests otherwise! I have a window and window controller which in the absence of an object controller work fine, and both are deallocated when the window is closed. If I add an ObjectController to the NIB and bind its Content Object to File's Owner.self then the window no longer closes properly. The window disappears from the screen but the controller is not released as it should be. I get a windowWillClose notification, but the one [self autorelease] that I do from there is not enough to release the window. The controller appears to be still retained by the ObjectController. In the actual NIB there are various GUI elements bound to the object controller, but I have removed all those bindings, just leaving the single binding from the OC to File's Owner.self and I still have this problem of non-deallocation. If I remove that final binding, so the object controller is completely isolated, the window controller releases as one would expect (though I suspect the object controller may be leaked). Is there something important that I should be doing here? Should I somehow be releasing the object controller, or indicating to it that it is no longer required? I realise that the information I've given here may be incomplete, because I don't even know what factors may be important in understanding the problem! Any advice would be very welcome though, as I am completely out of ideas... Regards, Jonathan.___ 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
ObjectController preventing WindowController from releasing
Sorry. Re-sending under what I think is a more correct title. I only realised after I hit send! Begin forwarded message: From: Jonathan Taylor j.m.tay...@durham.ac.uk Date: 7 November 2011 16:08:13 GMT To: cocoa-dev cocoa-dev@lists.apple.com Subject: ObjectController preventing window from closing Hi all, This is probably a very basic question, but I am out of ideas and hoping someone can offer some help. I should say that I'm afraid I'm somewhat out of my depth with ObjectControllers: I added some seemingly simple bindings at the recommendation of a poster on here, and I thought I understood what it was doing, but the fact that I am now having retain issues suggests otherwise! I have a window and window controller which in the absence of an object controller work fine, and both are deallocated when the window is closed. If I add an ObjectController to the NIB and bind its Content Object to File's Owner.self then the window no longer closes properly. The window disappears from the screen but the controller is not released as it should be. I get a windowWillClose notification, but the one [self autorelease] that I do from there is not enough to release the window. The controller appears to be still retained by the ObjectController. In the actual NIB there are various GUI elements bound to the object controller, but I have removed all those bindings, just leaving the single binding from the OC to File's Owner.self and I still have this problem of non-deallocation. If I remove that final binding, so the object controller is completely isolated, the window controller releases as one would expect (though I suspect the object controller may be leaked). Is there something important that I should be doing here? Should I somehow be releasing the object controller, or indicating to it that it is no longer required? I realise that the information I've given here may be incomplete, because I don't even know what factors may be important in understanding the problem! Any advice would be very welcome though, as I am completely out of ideas... Regards, Jonathan. ___ 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: ObjectController preventing WindowController from releasing
Hi Ken, Thanks very much for your reply! I have a window and window controller which in the absence of an object controller work fine, and both are deallocated when the window is closed. If I add an ObjectController to the NIB and bind its Content Object to File's Owner.self then the window no longer closes properly. What is the File's Owner? Is the window controller the file's owner? Yes, the window controller is the file's owner, bound to the window, and with the window controller set up to be the delegate for the window. Is the window controller the one loading the NIB (rather than, say, using NSBundle or NSNib directly)? NSWindowController has some built-in functionality to break retain cycles for binding through File's Owner when and only when it is the File's Owner and loads the NIB. Yes it loads the nib from its own init routine, via initWithWindowNibName What would you sensibly bind to the File's Owner itself, rather than one of its properties? In other words, what is bound to or through the object controller? OK, I am not absolutely sure I've understood what you're getting at here, but I will try and answer in two parts - firstly what I originally did, and still do for a number of other windows, followed by the exact situation for this window. It may be that I am doing something wrong in either or both of these, but it may help explain how I've ended up where I have. == What I originally did == The Content Object of the ObjectController is bound to File's Owner.self and various GUI text boxes are bound to variables within the file's owner e.g. a text box bound to Object Controller.selection.speed. Rightly or wrongly, the data model is contained within the window controller - it really didn't seem worth the effort of separating them out. Assuming I have set everything up correctly, this was originally suggested to me by a poster on here in order that I could make calls to [myObjectController commitEditing] when I needed to. == The actual situation for this window == I'm not sure if this is what you are getting at here, but actually in this specific case there IS a separation between window controller and data model. The window controller is a very lightweight class which keeps a pointer to the object camera that actually contains the data model. So the text boxes are actually bound to things like Object Controller.selection.camera.framerate. Are you suggesting that this could be the problem and I should be binding the Object Controller to File's Owner.camera instead of to File's Owner.self, and that this might help break retain cycles?___ 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: Keeping grayscale image grayscale
Belated thanks for the various replies to my question. I'm working through the posted code and links now and looking at what I can learn from it. One query though: On 12 Oct 2011, at 16:42, Heinrich Giesen wrote: Another rule of thumb is: if you need -[NSImage TIFFRepresentation] you do something wrong. (There are of course counterexamples). I've heard this said before, and have mostly eliminated it from my code. However the cocoadev page on NSBitmapImageRep does specifically say A correct use of TIFFRepresentation is one that sends the resulting data outside of the process. For example, write to disk, write to pasteboard, write to network. So is there a particular reason why there is a problem with my line: [[destImage TIFFRepresentation] writeToFile:destFile atomically:NO]; Thanks Jonny___ 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
Keeping grayscale image grayscale
I'm working with 16-bit grayscale images, and for the most part I'm just manipulating bits within NSBitmapImageRep objects. However for convenience it would be nice to do some stuff with NSImages, particularly when rescaling and suchlike. The problem is that whenever I draw into such an NSImage it gets converted to 3x8 bit RGB. Is there a simple way I can force things to stay grayscale, or am I fighting a losing battle here. The code snippet I have looks like this: NSImage *srcImage = [[NSImage alloc] initWithContentsOfFile:thePath]; NSImage *destImage = [srcImage copy]; // Attempt to encourage same 16-bit grayscale format as source [destImage setSize:destSize]; // Shrink dest image // Draw image into a new image at reduced size // This causes the result to be saved as a 3x8 bit RGB TIFF (which is not what I want!) [destImage lockFocus]; [srcImage drawInRect:destRect fromRect:srcRect operation:NSCompositeCopy fraction:1.0]; [destImage unlockFocus]; [[destImage TIFFRepresentation] writeToFile:destFile atomically:NO]; Does anyone have any suggestions? Thanks Jonny___ 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: dispatch_async Performance Issues
Hi Andreas, If I understand your post correctly, you are saying that you see a performance drop of 3x when using an iterator in your inner loop as opposed to using hand-written C code to do the iterating. Unfortunately you say you haven't actually posted the code relating to the iterator... but it seems to me that this is very likely to be the source of your problems! Your title states dispatch_async Performance Issues, but have you actually looked into whether you see the same problem in a single-threaded case that does not use dispatch_async? All I can suggest is that you examine the preprocessor output and even the generated assembly code with the aim of spotting any significant differences in the generated code in each case. It may well be that a function call is being generated as part of the iterator code, or something like that. Shark may help you pin down where the problem is, but you will probably need to have some level of appreciation of assembly code to be able to fully interpret the results for your optimized build. Unfortunately without the crucial part of your source code there's not a lot anyone else can do to help you in that respect... Hope that helps a bit Jonny___ 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: dispatch_async Performance Issues
... and more importantly I do not believe your code makes correct use of dispatch_group_async. Your first call adds a producer block to the global concurrent queue, which may start executing immediately. At some time soon afterwards you add a consumer block to the global concurrent queue, which again may start executing immediately - while the producer block is still in the process of producing. As far as I can see the code appears to have a number of major issues: 1. Theoretically your producer block may not have produced anything by the time your consumer block executes 2. What happens if your consumer block has processed all the currently-added blocks before the producer block has added the eof marker? 3. You have only one single consumer block, which means you will only have a single consumer thread running under Grand Central Dispatch, which rather defeats the purpose of using it at all! I think you may not have fully understood how GCD is intended to be used... 4. Are you sure that your mysterious and rather complicated-seeming CFDataConstBuffers class is sufficiently threadsafe for your producer to be adding to it at the same time as your consumer block is iterating through it? I am 99% sure that the explicit consumer code you wrote in ConcurrentProduceConsume is not threadsafe. Jonny.___ 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