Reputation: 21
I'm trying to migrate an objc project to swift3. I'm not sure how can I compare an array to nil. I have found this topic, but that was 2 years ago and the swift's syntax has changed a lot.
If I have a code like this in swift:
let variable = something as? NSArray
if variable == nil {
// do something
}
It won't let me to compare this variable with nil, causing an error "comparing this variable, always returns false". I have tried comparing variable.description with " ", but does it do the same thing? By "something" i meant:
var variable = dict.object(forKey: someString) as! NSArray
The main thing I wanted to do with this was:
var variable = dict.object(forKey: someString) as! NSArray
if variable == nil {
//create
}
else {
// append
}
Upvotes: 1
Views: 1062
Reputation: 32066
This line indicates that variable is and must be an NSArray. If dict.object(forKey: someString)
is not an NSArray, this will cause a crash
var variable = dict.object(forKey: someString) as! NSArray
// ^
// This exclamation mark means you are certain this is an NSArray
// Also, because there is no question mark after NSArray, this variable
// is not optional. It cannot be nil
However, you then use
if variable == nil {
And this is where the warning comes from. The variable can never be nil, because the variable is not optional
What you probably want is:
if let variable = dict.object(forKey:someString) as? NSArray
This will return false if:
dict.object(forKey:someString)
returns a nil objectAfter this variable
is now a non-optional NSArray. It is guaranteed to be an NSArray and is guaranteed to not be nil
. You can use it without unwrapping it. e.g.
if let variable = dict.object(forKey:someString) as? NSArray {
for element in variable {
}
}
else {
//The dict doesn't contain the object yet. `variable` is nil
//Create a new array and add it to dict
let newArray = ["First Value"]
dict[someString] = newArray
}
Upvotes: 1
Reputation: 7595
You can also use this format with guard-else
:
guard let variable = something as? NSArray else {
// your variable is nil. Do something if needed
}
// your variable is available in this scope. Do something when variable contains Array
Upvotes: 0
Reputation: 2906
That's what the optional unwrapping syntax is for. You can combine the unwrapping and cast into one if statement:
if let variable = something as? NSArray {
// variable is not nil and is an NSArray
// Now you can do something with it.
} else {
// Either something is nil or it is not able to be cast as an NSArray
// Handle this case.
}
I should also mention that if you don't need to use something
in Objective-C, then you should use the Swift-native array type. This can be declared like this:
let someArray = ["string1", "string2"]
Upvotes: 3
Reputation: 40211
let variable = something as? NSArray
With this declaration, variable
will be an optional type (NSArray?
) and never nil. This is because casting with as?
returns an optional value that either contains the successfully casted object or nothing. You can see this by alt-clicking the variable name in Xcode.
If you want to know whether it contains a value, you need to use the if let
syntax:
if let variable = variable {
// variable is guaranteed to be an NSArray here.
}
Upvotes: 0