> On Feb 22, 2017, at 2:05 PM, Rod Brown <[email protected]> wrote:
> 
> I think the big argument from you, Charles, is that the progress can become 
> arbitrarily badly performing, depending on its use, and that could have 
> untold effects up the chain with KVO notifications firing for minor elements 
> of work?
> 
> I think this is a fair observation that the responsibility of a reporter 
> shouldn’t be to rate limit the reporting rate for performance reasons. 
> Rather, the observer should be able to adjust the reporting rate to something 
> that is appropriate for the updates they wish to perform. A 50 pixel progress 
> bar only theoretically needs reporting every adjustment of 1/50 of the total 
> work, and other reporting and updating is superfluous and simply a 
> performance problem. But why is a data task responsible for knowing that? It 
> seems backwards.

Very much so. It has been my opinion for a long time that the back-end code is 
*not* the appropriate place for this stuff to be.

> Perhaps we need to examine the problem here, and how to solve that, rather 
> than the cause? Because I agree with Tony - replacing every use of KVO on a 
> performance basis isn’t a scalable solution.


Again, I am not advocating for replacing every use of KVO. For many cases, KVO 
is conceptually a great solution (even if I hate its implementation). For 
binding values in the UI to properties in your view controller? It’s great. For 
populating table views with arrays of values, or doing pretty much anything 
Core Data-related? It’s a godsend. However, for the specific task of progress 
reporting, IMO, it is Considered Harmful. We cannot reap the benefits of it, 
because of the threading issue.

Can we bind our UI elements to it to avoid glue code? No, because it might be 
updated on a background thread.

Okay, can we just be sure to wrap all updates on the main dispatch queue? No, 
because if we add any sub-progresses to the tree that are managed by opaque 
library code, we can’t know that the library will follow the same pattern. 
Also: without some kind of coalescing mechanism, we’ll end up with a crazy 
number of operations flooding the queue.

Can we fix KVO to make it fire on the main thread? No, because KVO is 
extensively used all over the Objective-C frameworks, and making such a large 
change to it is bound to break binary compatibility all over the place. Also, 
the need for the -willChangeValueForKey: method to complete before changing the 
property really hamstrings any attempts to make KVO thread-safe in a sane way.

Can we add some Swift-native KVO equivalent, and have that work the way we want 
it to? Yes, and this would be fantastic! But with Progress/NSProgress being the 
same class instead of a custom Swift class, we’d need to keep the Objective-C 
KVO system in place for compatibility with Objective-C code, which means we’ll 
still have the performance drawbacks of having -willChangeValueForKey: and 
-didChangeValueForKey: called every time we update it.

Can we just write our own KVO observer, observe the progress, and forward 
things to the main queue from there? Of course. But the UI for that is terrible 
compared to anything closure-based, so then why are we using KVO?

My opinion: KVO is cool for the things it’s good at, but it’s the wrong tool 
here.

Charles

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to