Re: Is slowing down bindings updates possible?
On Jan 19, 2012, at 1:33 , Ken Thomases wrote: On Jan 18, 2012, at 6:12 PM, Marcel Weiher wrote: On Jan 14, 2012, at 18:37 , Kyle Sluder wrote: Breaking this pattern should be a conscious decision. I'd say that the opposite is true: in general you should avoid specific model - view communication as per MVC (apart from invalidation), but in specialized and very simple cases you may be able to get away with it. KVO and bindings are not specific model - view communication, they are a generalized mechanism which avoid coupling. The model just supports a generalized observer pattern. It doesn't know anything about its observers; it doesn't even know or care whether there are any. Hi Ken! I have to admit that my thoughts on this are not 100% formed yet, but while I agree with you in theory, my observations from practice (mostly looking at code provided by people who work(ed) for me) are that this happy theory doesn't pan out in practice. What I see in KVO and NSNotification code is that instead of noting what has changed, the code immediately acts on that notification, usually by updating the UI. What you then have is not decoupled code, but coupled code (with at least temporal coupling) where the coupling is implicit rather than explicit. To me, implicitly coupled code is actually worse than explicitly coupled code (with actually decoupled code better than either). That's a fairly high-level wishy-washy type of information, and only my experience, though a very consistent experience. I think another bit that contributes to this problem is that both KVO and NSNotification call clients directly, rather than going through a queue that could, for example, be used for event coalescing. Because they are called directly, the effect is really very close to inserting a message-send right where you send the notification, and typically there is often only one or at most a couple of potential listeners for that notification, so you might as well just put in a delegate and make the dependency explicit (again assuming my valuation of implicit coupling as worse than explicit coupling is true). Your mileage may vary, Marcel ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Is slowing down bindings updates possible?
Does the OP mean slowing down binding's updates instead of slowing down bindings updates? The subject doesn't make any sense to me. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Is slowing down bindings updates possible?
Hi Kyle, On Jan 14, 2012, at 18:37 , Kyle Sluder wrote: On Jan 14, 2012, at 2:53 AM, Marcel Weiher marcel.wei...@gmail.com wrote: You shouldn't push updates to the UI, the UI should query the model, and it should do it at human speed, not at whatever speed the machine can manage to change the state. There are a bunch of reasons for this, not least is that UI updating is fairly heavyweight and you can actually impact your performance (significantly, in some cases). Be careful here. This is good advice in this particular circumstance, but in general pushing values to the UI is good and common design. While it sure is common, I have a hard time seeing what's good about this design. The sorts of update problems the OP saw are just one symptom of this approach. The UI will register as a KVO observer, or as an NSNotification observer, or perhaps the controller will just call -setObjectValue: directly. In my experience and opinion most of these are tempting, but ultimately lead to bad results because of the type of model to view coupling that you are supposed to avoid in MVC. The model should be able to send invalidation notices to the view, but not push values. The view should react to the invalidation notices by requesting new values from the model. At least this is how the original Smalltalk MVC worked ( models are ideally passive and don't even know about views, controllers manage the changes; if that doesn't work, models send #changed, which then causes the view to take proper action to react to that change). One place where this is illustrated well is view drawing. You don't have the model push to have bits of the view drawn as the updates happen (for example sending drawRect: directly to the view). Instead you have parts of the view invalidated, and invalidations accumulated, until the view is ready to redraw all the invalidated areas at once. Breaking this pattern should be a conscious decision. I'd say that the opposite is true: in general you should avoid specific model - view communication as per MVC (apart from invalidation), but in specialized and very simple cases you may be able to get away with it. For example, you don't push a value to cell-based NSTableViews; you tell the table view it needs to ask you for the values at certain indexes. This is because cell-based table views are an optimization that avoids keeping tons of view objects around. …and another is NSTableView :-) [snip] Marcel ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post 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: Is slowing down bindings updates possible?
On Jan 18, 2012, at 6:12 PM, Marcel Weiher wrote: On Jan 14, 2012, at 18:37 , Kyle Sluder wrote: The UI will register as a KVO observer, or as an NSNotification observer, or perhaps the controller will just call -setObjectValue: directly. In my experience and opinion most of these are tempting, but ultimately lead to bad results because of the type of model to view coupling that you are supposed to avoid in MVC. The model should be able to send invalidation notices to the view, but not push values. The view should react to the invalidation notices by requesting new values from the model. At least this is how the original Smalltalk MVC worked ( models are ideally passive and don't even know about views, controllers manage the changes; if that doesn't work, models send #changed, which then causes the view to take proper action to react to that change). What you are saying should be the case is, in fact, exactly how KVO and bindings actually work. You seem to be vehemently agreeing with Kyle, while claiming to be disagreeing. Breaking this pattern should be a conscious decision. I'd say that the opposite is true: in general you should avoid specific model - view communication as per MVC (apart from invalidation), but in specialized and very simple cases you may be able to get away with it. KVO and bindings are not specific model - view communication, they are a generalized mechanism which avoid coupling. The model just supports a generalized observer pattern. It doesn't know anything about its observers; it doesn't even know or care whether there are any. 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Is slowing down bindings updates possible?
On Wed, Jan 18, 2012 at 4:33 PM, Ken Thomases k...@codeweavers.com wrote: On Jan 18, 2012, at 6:12 PM, Marcel Weiher wrote: On Jan 14, 2012, at 18:37 , Kyle Sluder wrote: Breaking this pattern should be a conscious decision. I'd say that the opposite is true: in general you should avoid specific model - view communication as per MVC (apart from invalidation), but in specialized and very simple cases you may be able to get away with it. KVO and bindings are not specific model - view communication, they are a generalized mechanism which avoid coupling. The model just supports a generalized observer pattern. It doesn't know anything about its observers; it doesn't even know or care whether there are any. And, importantly, the exact same observer interface can be used by view objects, controller objects, or anything else. We often have controller-layer objects that interpose between our views and model objects. But there's no sense _forcing_ this arrangement if it offers no benefit. --Kyle Sluder ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post 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: Is slowing down bindings updates possible?
I'm not sure if this has already been suggested: What if you don't update the UI unless the change is at least 1 sec or 1% or certain amount of bytes (whatever suits your needs better)? Leo On 1/15/12 12:33:31 AM, Andrew wrote: Thank you all for the opinions. I left the code as-is in terms of binding, but changed my rate calculations to use a weighted running average. After doing so, the estimated seconds tick by one at a time for the most part, and the rate is more constant. This is a tool for me and some co-workers, so at this point, it is good enough. But the ideas are sound and if it bothers me enough, I may decouple the UI from the model by not using bindings at some point and use a timer based approach. On Sat, Jan 14, 2012 at 10:37 AM, Kyle Sluderkyle.slu...@gmail.com wrote: On Jan 14, 2012, at 2:53 AM, Marcel Weihermarcel.wei...@gmail.com wrote: Hi Andrew, On Jan 13, 2012, at 6:57 , Andrew wrote: The result of this is that the UI updates really frequently and the estimated time to complete and the download rate jump around a lot. I would love it if I could tell cocoa to only update the UI once per second instead of immediately when the property key changes. You shouldn't push updates to the UI, the UI should query the model, and it should do it at human speed, not at whatever speed the machine can manage to change the state. There are a bunch of reasons for this, not least is that UI updating is fairly heavyweight and you can actually impact your performance (significantly, in some cases). Be careful here. This is good advice in this particular circumstance, but in general pushing values to the UI is good and common design. The UI will register as a KVO observer, or as an NSNotification observer, or perhaps the controller will just call -setObjectValue: directly. Breaking this pattern should be a conscious decision. For example, you don't push a value to cell-based NSTableViews; you tell the table view it needs to ask you for the values at certain indexes. This is because cell-based table views are an optimization that avoids keeping tons of view objects around. But view-based table views behave just like any other view: you push updates directly to the controls contained within your table cell view. In Andrew's case, it's clear that he should deviate from the norm, and the UI should be in charge of asking for the latest value at a rate that makes sense, probably controlled by an NSTimer. --Kyle Sluder ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post 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/leo.r%40rogers.com This email sent to le...@rogers.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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Is slowing down bindings updates possible?
Hi Andrew, On Jan 13, 2012, at 6:57 , Andrew wrote: The result of this is that the UI updates really frequently and the estimated time to complete and the download rate jump around a lot. I would love it if I could tell cocoa to only update the UI once per second instead of immediately when the property key changes. You shouldn't push updates to the UI, the UI should query the model, and it should do it at human speed, not at whatever speed the machine can manage to change the state. There are a bunch of reasons for this, not least is that UI updating is fairly heavyweight and you can actually impact your performance (significantly, in some cases). With a bit of work I could probably set up a proxy object for each download that would do something like that and use timer, but it would be a lot of messy code. Not sure why you would need a proxy, or complicated code. For any long-running task I have I tend to add a method percentDone to the object in question ( (100.0 * currentBytes) / totalBytes or some such ) and then have a timer query that and update the progress bar etc. Easy peasy. I could also just delay updating the _bytesDownloaded on a queue. Or a third idea is to cache the estimated calc time and rate and then only recalculate the value at most once per second. The estimate is a separate issue, but also one where you definitely want to decouple. Cheers, Marcel ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post 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: Is slowing down bindings updates possible?
On Jan 14, 2012, at 2:53 AM, Marcel Weiher marcel.wei...@gmail.com wrote: Hi Andrew, On Jan 13, 2012, at 6:57 , Andrew wrote: The result of this is that the UI updates really frequently and the estimated time to complete and the download rate jump around a lot. I would love it if I could tell cocoa to only update the UI once per second instead of immediately when the property key changes. You shouldn't push updates to the UI, the UI should query the model, and it should do it at human speed, not at whatever speed the machine can manage to change the state. There are a bunch of reasons for this, not least is that UI updating is fairly heavyweight and you can actually impact your performance (significantly, in some cases). Be careful here. This is good advice in this particular circumstance, but in general pushing values to the UI is good and common design. The UI will register as a KVO observer, or as an NSNotification observer, or perhaps the controller will just call -setObjectValue: directly. Breaking this pattern should be a conscious decision. For example, you don't push a value to cell-based NSTableViews; you tell the table view it needs to ask you for the values at certain indexes. This is because cell-based table views are an optimization that avoids keeping tons of view objects around. But view-based table views behave just like any other view: you push updates directly to the controls contained within your table cell view. In Andrew's case, it's clear that he should deviate from the norm, and the UI should be in charge of asking for the latest value at a rate that makes sense, probably controlled by an NSTimer. --Kyle Sluder___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post 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: Is slowing down bindings updates possible?
Thank you all for the opinions. I left the code as-is in terms of binding, but changed my rate calculations to use a weighted running average. After doing so, the estimated seconds tick by one at a time for the most part, and the rate is more constant. This is a tool for me and some co-workers, so at this point, it is good enough. But the ideas are sound and if it bothers me enough, I may decouple the UI from the model by not using bindings at some point and use a timer based approach. On Sat, Jan 14, 2012 at 10:37 AM, Kyle Sluder kyle.slu...@gmail.com wrote: On Jan 14, 2012, at 2:53 AM, Marcel Weiher marcel.wei...@gmail.com wrote: Hi Andrew, On Jan 13, 2012, at 6:57 , Andrew wrote: The result of this is that the UI updates really frequently and the estimated time to complete and the download rate jump around a lot. I would love it if I could tell cocoa to only update the UI once per second instead of immediately when the property key changes. You shouldn't push updates to the UI, the UI should query the model, and it should do it at human speed, not at whatever speed the machine can manage to change the state. There are a bunch of reasons for this, not least is that UI updating is fairly heavyweight and you can actually impact your performance (significantly, in some cases). Be careful here. This is good advice in this particular circumstance, but in general pushing values to the UI is good and common design. The UI will register as a KVO observer, or as an NSNotification observer, or perhaps the controller will just call -setObjectValue: directly. Breaking this pattern should be a conscious decision. For example, you don't push a value to cell-based NSTableViews; you tell the table view it needs to ask you for the values at certain indexes. This is because cell-based table views are an optimization that avoids keeping tons of view objects around. But view-based table views behave just like any other view: you push updates directly to the controls contained within your table cell view. In Andrew's case, it's clear that he should deviate from the norm, and the UI should be in charge of asking for the latest value at a rate that makes sense, probably controlled by an NSTimer. --Kyle Sluder ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post 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: Is slowing down bindings updates possible?
On Jan 12, 2012, at 10:57 PM, Andrew wrote: I have a download controller with an NSMutableArray and an NSArrayController hooked up to a NSTableView with a view based setup. My array contains custom download objects. Each of those has a NSURLDownload instance. Basically, I am showing a browser-download like interface with size downloaded, total expected size, a progress bar, time elapsed, download rate and estimated time left. It is all working wonderfully, but actually too well. Right now, I am using will/didChangeValueForKey messages to notify observers when the number of bytes downloaded changes. I am doing this in the callback method: - (void)download:(NSURLDownload *)download didReceiveDataOfLength:(NSUInteger)length { [self willChangeValueForKey:@bytesDownloaded]; _bytesDownloaded += length; [self didChangeValueForKey:@bytesDownloaded]; } The result of this is that the UI updates really frequently and the estimated time to complete and the download rate jump around a lot. I would love it if I could tell cocoa to only update the UI once per second instead of immediately when the property key changes. It may well be your calculation. Do you keep a byte count array and average over that? This kind of approach usually smooths out jumps in data size after the first few. Other than that, there isn't really anything you can do except update bytes only via a timer, but even that won't work all the time if you consistently experience data jumps. Unless you slow the timer down to a point that might be user-unfriendly… This approach might require a lot of trial and error to get right. Anyway, all the timer callback has to do is send the willChange/DidChange, which doesn't sound very messy to me. Alternatively, of course, you could use BSD sockets and control the data buffering to force consistency. HTH, Keary Suska Esoteritech, Inc. Demystifying technology for your home or business ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post 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: Is slowing down bindings updates possible?
Why don't you just decouple your UI from the by-the-millisecond download process? For example, you could update calculated values whenever the value of bytesDownloaded changes but use a NSTimer to update the display of those values maybe once or twice a second. The display is then sampling the download process periodically rather than recording every single change, which should also reduce the amount of time spent redrawing the display. On Jan 12, 2012, at 9:57 PM, Andrew wrote: I have a download controller with an NSMutableArray and an NSArrayController hooked up to a NSTableView with a view based setup. My array contains custom download objects. Each of those has a NSURLDownload instance. Basically, I am showing a browser-download like interface with size downloaded, total expected size, a progress bar, time elapsed, download rate and estimated time left. It is all working wonderfully, but actually too well. Right now, I am using will/didChangeValueForKey messages to notify observers when the number of bytes downloaded changes. I am doing this in the callback method: - (void)download:(NSURLDownload *)download didReceiveDataOfLength:(NSUInteger)length { [self willChangeValueForKey:@bytesDownloaded]; _bytesDownloaded += length; [self didChangeValueForKey:@bytesDownloaded]; } The result of this is that the UI updates really frequently and the estimated time to complete and the download rate jump around a lot. I would love it if I could tell cocoa to only update the UI once per second instead of immediately when the property key changes. With a bit of work I could probably set up a proxy object for each download that would do something like that and use timer, but it would be a lot of messy code. I could also just delay updating the _bytesDownloaded on a queue. Or a third idea is to cache the estimated calc time and rate and then only recalculate the value at most once per second. Any other brighter ideas? Thoughts? ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post 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
Is slowing down bindings updates possible?
I have a download controller with an NSMutableArray and an NSArrayController hooked up to a NSTableView with a view based setup. My array contains custom download objects. Each of those has a NSURLDownload instance. Basically, I am showing a browser-download like interface with size downloaded, total expected size, a progress bar, time elapsed, download rate and estimated time left. It is all working wonderfully, but actually too well. Right now, I am using will/didChangeValueForKey messages to notify observers when the number of bytes downloaded changes. I am doing this in the callback method: - (void)download:(NSURLDownload *)download didReceiveDataOfLength:(NSUInteger)length { [self willChangeValueForKey:@bytesDownloaded]; _bytesDownloaded += length; [self didChangeValueForKey:@bytesDownloaded]; } The result of this is that the UI updates really frequently and the estimated time to complete and the download rate jump around a lot. I would love it if I could tell cocoa to only update the UI once per second instead of immediately when the property key changes. With a bit of work I could probably set up a proxy object for each download that would do something like that and use timer, but it would be a lot of messy code. I could also just delay updating the _bytesDownloaded on a queue. Or a third idea is to cache the estimated calc time and rate and then only recalculate the value at most once per second. Any other brighter ideas? Thoughts? Thank you, Andrew ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post 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: Is slowing down bindings updates possible?
The result of this is that the UI updates really frequently and the estimated time to complete and the download rate jump around a lot. I would love it if I could tell cocoa to only update the UI once per second instead of immediately when the property key changes. I don't believe there is such a feature. Though I wouldn't be surprised if someone out there has already implemented a proxy like you suggest. With a bit of work I could probably set up a proxy object for each download that would do something like that and use timer, but it would be a lot of messy code. I could also just delay updating the _bytesDownloaded on a queue. Or a third idea is to cache the estimated calc time and rate and then only recalculate the value at most once per second. I think if you're going to follow the MVC paradigm, you should be sure to update _bytesDownloaded immediately - that's your model, which should always be accurate. Any smoothing or aggregation or whatever else you want for UI purposes should be handled in your controller. So, either a reusable proxy object (if you'd like to stick with bindings), or just coded in your controller such that it won't update the view at more than N Hz (in which case simply modifying the UI manually from your controller is probably the easiest option). Either way the implementation shouldn't be that tricky - just a timer and a last-updated timestamp. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post 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