I make SnapOperationQueue which is an operation queue with a few extensions I like. One of them is reprioritisation of groups of operations. An operation is added with one of these four priorities (SnapOperationQueuePriority):
case Highest
case High
case Normal
case Low
In the current implementation I have it so that .Low and .Highest will not change, but .High and .Normal will.
I would like to change this so that I can have upper and lower thresholds on priorities. I.e, I can say that this operation that we might as well do now (.Low) can become super-important in a bit (.High) i.e. when pre-caching images and that image is all the sudden needed on screen. These thresholds should also be able to say that some operations, even in a group that is reprioritised, will not be reprioritised lower than something, i.e. a login operation (.Highest) should remain .Highest
To do this, I wanted to modify my enum like this:
case Highest(lowerThreshold: SnapOperationQueuePriority = .Highest)
case High(lowerThreshold: SnapOperationQueuePriority = .Low, higherThreshold: SnapOperationQueuePriority = .High)
case Normal(lowerThreshold: SnapOperationQueuePriority = .Low, higherThreshold: SnapOperationQueuePriority = .High)
case Low(higherThreshold: SnapOperationQueuePriority = .Low)
However, I get "Default argument not permitted in a touple type". The reason I want to have default arguments here is so that this change won't break or change behaviour of any code that is already using the existing implementation.
Can you suggest a way in which I can get my new priorities yet don't change the API for code that depends on the current API?
The default value of an enum E is the value produced by the expression (E)0 . Without overriding the default values, printing default(E) returns Foo since it's the first-occurring element.
Each raw value for our enum case must be a unique string, character, or value of any integer or floating-point type. This means the value for the two case statements cannot be the same.
Types in Swift fall into one of two categories: first, “value types”, where each instance keeps a unique copy of its data, usually defined as a struct, enum, or tuple. The second, “reference types”, where instances share a single copy of the data, and the type is usually defined as a class.
Swift's Enum can have methods. It can have instance methods and you can use it to return expression value for the UI. Let's look at the code above.
FYI: Default parameter values are now allowed after Swift 5.1. This answer only applies to versions of Swift before that.
This is a tricky one because you cannot have default values, you cannot have stored properties and you cannot repeat case names in enums. The best thing I can think to do is to create an init() and some semi-private cases.
enum SnapOperationQueuePriority {
case Highest, High, Low, Default
}
enum SnapOperationQueue {
case Highest, High, Normal, Low
case _Highest(lowerThreshold: SnapOperationQueuePriority)
case _High(lowerThreshold: SnapOperationQueuePriority, higherThreshold: SnapOperationQueuePriority)
case _Normal(lowerThreshold: SnapOperationQueuePriority, higherThreshold: SnapOperationQueuePriority)
case _Low(higherThreshold: SnapOperationQueuePriority)
init(queue:SnapOperationQueue, lowerThreshold:SnapOperationQueuePriority = .Default, higherThreshold:SnapOperationQueuePriority = .Default) {
switch queue {
case .Highest:
self = ._Highest(lowerThreshold: lowerThreshold == .Default ? .Highest : lowerThreshold)
case .High:
self = ._High(lowerThreshold: lowerThreshold == .Default ? .Low : lowerThreshold, higherThreshold: higherThreshold == .Default ? .High : higherThreshold)
case .Normal:
self = ._Normal(lowerThreshold: lowerThreshold == .Default ? .Low : lowerThreshold, higherThreshold: higherThreshold == .Default ? .High : higherThreshold)
case Low:
self = ._Low(higherThreshold: higherThreshold == .Default ? .Low : higherThreshold)
default:
self = queue
}
}
}
SnapOperationQueue.Normal
SnapOperationQueue(queue: .Normal)
SnapOperationQueue(queue: .High, lowerThreshold: .High, higherThreshold: .Highest)
This keeps old implementations valid and catches new ones made using init. In addition you might add a method like this to the enum:
func queue() -> SnapOperationQueue {
switch self {
case .Highest:
return SnapOperationQueue(queue: .Highest)
case .High:
return SnapOperationQueue(queue: .High)
case .Normal:
return SnapOperationQueue(queue: .Normal)
case Low:
return SnapOperationQueue(queue: .Low)
default:
return self
}
}
So that you can transform the old types of enum cases into the new, e.g. SnapOperationQueue.Normal.queue()
This is now possible starting with Swift 5.1 (Xcode 11)
See the feature proposal.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With