问题
I've run into this a on a couple functions in Swift 2.0 and wondering if there is a work around. There seems to be no way to not specify enum arguments in Swift 2.0 now. For example, these two methods seem to require something other than nil
or 0
be passed in. Is there a way around this?
// Cannot invoke '...' with argument list of type ... options: Int
NSCalendar.currentCalendar().dateByAddingComponents(components, fromDate: self.date, options: 0)
NSJSONSerialization.JSONObjectWithData(data, options: 0)
// Cannot invoke '...' with argument list of type ... options: nil
NSCalendar.currentCalendar().dateByAddingComponents(components, fromDate: self.date, options: nil)
NSJSONSerialization.JSONObjectWithData(data, options: nil)
回答1:
Options are now specified as a set, so just pass an empty set: options: []
.
回答2:
Just to add some more detail: the types in question, like NSJSONReadingOptions, are declared as NS_OPTIONS
in Obj-C.
Before Swift 2
Prior to Swift 2, these were imported to Swift as RawOptionSetType, which required BitwiseOperationsType and NilLiteralConvertible. This allowed you to pass nil
, and to combine values with operators a | b
, a & ~b
, etc.
/// Protocol for `NS_OPTIONS` imported from Objective-C
protocol RawOptionSetType : BitwiseOperationsType, NilLiteralConvertible { ...
protocol BitwiseOperationsType {
func &(lhs: Self, rhs: Self) -> Self
func |(lhs: Self, rhs: Self) -> Self
func ^(lhs: Self, rhs: Self) -> Self
prefix func ~(x: Self) -> Self
static var allZeros: Self { get }
}
Nowadays
In Swift 2 it's been generalized a bit more. These are now OptionSetType, which requires SetAlgebraType and RawRepresentable. (The underlying RawValue
type may or may not be BitwiseOperationsType.)
public protocol OptionSetType : SetAlgebraType, RawRepresentable {
typealias Element = Self
public init(rawValue: Self.RawValue)
}
public protocol SetAlgebraType : Equatable, ArrayLiteralConvertible {
typealias Element
public init()
public func contains(member: Self.Element) -> Bool
public func union(other: Self) -> Self
public func intersect(other: Self) -> Self
public func exclusiveOr(other: Self) -> Self
// and more...
}
SetAlgebraType isn't NilLiteralConvertible anymore, but it is ArrayLiteralConvertible, so you can use []
instead of nil
to mean "no options".
And you can combine multiple options in an array: options: [.MutableLeaves, .AllowFragments]
.
SetAlgebraType also has much more readable function names than those bitwise operators &
, |
, ^
, etc:
public func contains(member: Self.Element) -> Bool
public func union(other: Self) -> Self
public func intersect(other: Self) -> Self
public func exclusiveOr(other: Self) -> Self
So you can use if jsonOptions.contains(.AllowFragments) { ...
and such.
回答3:
You pass []
(an empty set)
Some enums
have an explicit option that means 0
, but Swift 3 sometimes do not import these, because []
means the same thing. Like UIViewAutoresizing
's UIViewAutoresizingNone
来源:https://stackoverflow.com/questions/32169597/swift-2-0-nil-or-0-enum-arguments