I used XCode6 beta4 to develop my project via obj-c and Swift. After I've installed GM version every
self.view.addSubview(startButton)
Highlighted and also these lines are highlighted
scene.view.paused
self.scene.removeAllActions()
self.view.bounds
are SpriteKit classes changed or it's my fault or it's GM's bug?
error is SKView/SKScene does not have a member **** , but I checked it, it HAS those members.
I know I've seen several effective duplicates already, but I'm not finding them at the moment, so here's a quick answer.
This has to do with how object parameters, return values, and properties in APIs are imported from ObjC to Swift. Earlier in the Xcode 6 beta period, all object params/returns/properties were imported as implicitly unwrapped optionals; e.g.
// in SKScene:
var view: UIView!
// in SKNode:
var children: [AnyObject]!
With an implicitly unwrapped optional (IUO), you can address view directly (so code like self.view.bounds is legal). It might not exist, in which case you'll get a crash. And some operations aren't possible on an IUO type that are possible on the type it contains. The best practice for IUOs is to check them for nil, using constructs like optional chaining and optional binding, before working with their contents.
The ObjC-to-Swift importer has to do this for all properties/params/returns that are pointers to ObjC objects because syntactically any pointer is allowed to be nil, even if in practice it will never be. Testing for nil gets kinda cumbersome for APIs like SKNode.children that are never nil (it's an empty array in the no-children case).
Over the last few betas and the Xcode 6 GM, Apple audited several frameworks so that imported object pointers that can possibly be nil (like UIViewController.view) import as explicit Optionals:
// SKScene
var view: UIView?
And object pointers that will never be nil import as non-optional types:
// SKNode
var children: [AnyObject]
This means that you can safely reference node.children without worrying about a crash and without needing to check it for nil. But now that scene.view is explicitly optional, you must check it for nil before using it.
Depending on the scenario, you might choose any of several ways to test or otherwise deal with an optional:
Force unwrap: self.view!.bounds.size
Optional chaining: self.view?.bounds.size
Optional binding: if let view = self.view { /* do something with */ view.bounds.size }
Chaining and Binding: if let size = self.view?.bounds.size { /* do something with */ size }
Read up on Optionals in The Swift Programming Language for details on the advantages and disadvantages of each.
It's not your fault really. The Swift team went through and cleaned up the use of optionals in the frameworks. In some cases, implicitly unwrapped optionals (declared with !) became regular optionals (declared with ?).
The view is now an optional declared with ? instead of an implicitly unwrapped optional declared with !. You now need to unwrap the value when using it:
self.view?.bounds.size
Related
I know we need to define the parameter of function in Swift to be neither implicit unwrapped optional or optional, to make it non-nil. However I am not sure what is more conventional between implicit unwrapped optional or optional.
I am watching WWDC 2014 Swift interoperability in depth and a bit confused with two examples shown in the slides. Basically it is about whether we should use implicit optional or unwrap parameters when defining function.
Example from Video
Below is the screenshot from that WWDC 2014 Swift interoperability in depth (At 09:01)
And the quote from the speaker is
You see again this is an implicit unwrapped optional, so that you can
pass a nil block in here.
Notice here both url and completionHandler are implicit unwrapped optionals, and we can pass in nil into it. All good!
Example from Header file
However when I check UIKit UITableViewCell, I find most of the methods are defined with optional parameters, such as
init(style: UITableViewCellStyle, reuseIdentifier: String?)
And basically it is suggesting those parameters can be nil too.
Seems like both ? and ! try to suggest the same thing (it can be nil).
I understand that ? means we will wrap whatever value to optional value (even for nil), and ! means we will unwrap it if what is passed in is an optional value. But I am not sure whether we should use ! or ?. And which is conventional?
Update
Looks like the video from WWDC 2014 is not quite correct or out-dated. Screenshot from the video shows UIDocument header file, which was different from the current UIKit header. It looks like at that time, all of them were defined as !. But now it is either ? or plain type.
WWDC 2014 Swift interoperability in depth (At 16:25)
Current header file
? is a shortcut for Optional<T> type
! is a shortcut for ImplicitlyUnwrappedOptional<T> type
Both types implement NilLiteralConvertible. This mean they have init(nilLiteral: ()) and can be initialized by Void. This could be syntatically-sugard in code by compiler into regular assignement of nil to a NilLiteralConvertible variable. Here are some code lines that from compiler standpoint mean the same:
let sweetOptionalInt: Int? = nil
let semiSweetOptionalInt: Optional<Int> = nil
let unsweetenedOptionalInt: Optional<Int> = Optional<Int>(nilLiteral: Void)
The same is true for ImplicitlyUnwrappedOptional.
So both could be initialized by nil, but behaviors of these types are different:
ImplicitlyUnwrappedOptional do unwrapping for you with an assumption
when you do a call object is already provided (but could be nil
before), so if it is not then application will crash with a runtime error.
Optional will require you to provide information how to unwrap variables.
As for interoperability while ago Objective-C didn't have a way to express nullability of variables. This is why most of APIs was converted with ! that stands for "proceed further if you dare" Recently Apple introduced nullability annotations for Objective-C. Apple augumented their APIs with these annotations, so now it is easier and safer to use methods with an extra nullability guidance in Swift.
You aren't quite right. "!" is the "force unwrap" operator. It says "This is an optional, but I guarantee that when this code runs, it won't be nil." If you are wrong, you crash.
if you are writing a function that takes a parameter that can be legitimately nil, use "?", which makes it an Optional. Then in the code of your function, you have to handle the case where it is nil.
Let's say we have:
let a:Int? = nil
// block not executed - unwapping done, type is inferred
if let unwrapped_a = a {
println(unwrapped_a)
}
// block not executed - unwrapping done, type is specified
if let unwrapped_a:Int = a {
println(unwrapped_a)
}
// block gets executed - unwrapping not done, new local constant + assignment is done instead?
if let not_unwrapped_a:Int? = a {
println(not_unwrapped_a)
}
So should I assume that Swift does an unwrapping in the first case, but an assignment in the second case?
Isn't this syntax a bit too close to create confusion? I mean, yes, the compiler warns you that you're using an optional type when working with not_unwrapped_a, but still.
Update:
So after Airspeed Velocity's answer I found another (but actually the same) weird case:
if let not_unwrapped_a:Int???? = a {
println(not_unwrapped_a)
}
a will be silently wrapped in an Int????. So it will be a type of Int????? (five) - because a was already an optional. And then it will get unwrapped once.
Case 1 and case 2 are identical – they are both assignments of the contents of a to a new variable. The only difference is you are leaving Swift to infer the type of unwrapped_a in option 1, whereas you’re manually giving the type in option 2. The main reason you’d ever need to do option 2 is if the source value were ambiguous – for example if it were an overloaded function that could return multiple types.
Case 3 is quite interesting.
Whenever you have a value, Swift will always be willing to silently upgrade it to an optional wrapping the value, if it helps make the types match and the code compile. Swift auto-upgrading of types is fairly rare (it won’t implicitly upgrade an Int16 to an Int32 for example) but values to optionals is an exception.
This means you can pass values wherever an optional is needed without having to bother to wrap it:
func f(maybe: Int?) { ... }
let i = 1
// you can just pass a straight value:
f(i)
// Swift will turn this into this:
f(Optional(i))
So in your final example, you’ve told Swift you want not_unwrapped_a to be an Int?. But it’s part of a let that requires a to be unwrapped before it’s assigned to it.
Presented with this, the only way Swift can make it work is to implicitly wrap a in another optional, so that’s what it does. Now it is an optional containing an optional containing nil. That is not a nil-valued optional - that is an optional containing a value (of an optional containing nil). Unwrapping that gives you an optional containing nil. It seems like nothing happened. But it did - it got wrapped a second time, then unwrapped once.
You can see this in action if you compile your sample code with swiftc -dump-ast source.swift. You’ll see the phrase inject_into_optional implicit type='Int??’. The Int?? is an optional containing an optional.
Optionals containing optionals aren’t obscure edge cases - they can happen easily. For example if you ever for…in over an array containing optionals, or used a subscript to get a value out of a dictionary that contained optionals, then optionals of optionals have been involved in that process.
Another way of thinking about this is if you think of if let x = y { } as kind of* like a function, if_let, defined as follows:
func if_let<T>(optVal: T?, block: T->()) {
if optVal != nil {
block(optVal!)
}
}
Now imagine if you supplied a block that took an Int? – that is, T would be an Int?. So T? would be a Int??. When you passed a regular Int? into if_let along with that block, Swift would then implicitly upgrade it to an Int?? to make it compile. That’s essentially what’s happening with the if let not_unwrapped_a:Int?.
I agree, the implicit optional upgrade can sometimes be surprising (even more surprising is that Swift will upgrade functions that return optionals, i.e. if a function takes an (Int)->Int?, it will upgrade an (Int)->Int to return an optional instead). But presumably the feeling is the potential confusion is worth it for the convenience in this case.
* only kind of
The purpose of the optional binding is to check an optional for not nil, unwrap and assign to a non optional of the type enclosed in the optional. So in my opinion the 1st case is the correct way of using it - the only variation I would use is adding an optional cast (useful for example when the optional contains AnyObject).
I wouldn't use the 2nd case, preferring an optional cast:
if let unwrapped_a = a as? Int { ... }
unless, as noted by #drewag in comments, the type is explicitly specified to avoid ambiguities when it's not clear.
In my opinion the 3rd case should generate a compilation error. I don't see any use of optional binding to assign an optional to another optional. Optional binding is not a generic inline assignment (such as if let x = 5 {...}), so conceptually it should not work if the left side is an optional - it should be handled the same way as if the right side is not an optional (for which compilation fails instead).
The Apple Swift Programming Language guide mentions the existence of the init! initializer, but does not provide any example for it. (Search for init! in this page)
I understand the use of a normal failable initializer declared with init?, but I fail to get the need of this other version. What is it needed for? Can somebody provide an example?
This serves two purposes:
When importing Cocoa APIs that Swift doesn't know about. If Swift does not know if an initializer can return nil or not, it annotates it with ! so that the developer knows there might be a nil hiding there, without forcing the dev to test for nil if there's actually no reason to.
For the same reasons implicitly-unwrapped optionals are used in other contexts (you may be willing to trade compile-time safety for added convenience in some cases).
I belive it's absolutely the same use of ! as in optionals. init? will return an optional. init! will return an implicitly unwrapped optional.
Implicitly unwrapped optionals are needed for calling Obj-C APIs where you are not sure whether it can return an optional or not. So you use an implicitly unwrapped optional and it behaves like a non-optional type but it will crash if an optional is returned.
Note that when Swift was introduced most Obj-C frameworks returned only implicitly unwrapped optionals but currently a lot of them return optionals or non-optional types because Apple is going through the code and checks whether they can return an optional or not. init! is needed everywhere where Apple hasn't tagged the initializers correctly yet.
Good question Matteo, I´m looking answer for the same question because init! don´t have sense (if it always init an object and we don´t need optional), but I haven´t found any clear answer.
I think that it´s because Apple haven´t finished his work: "...own Objective-C classes, and classes in frameworks that have not yet been audited, initializers are imported as init! ..."
Perhaps be util for you, the text in "Interacting with Objective-C APIs"(Apple)
"In Objective-C, initializers directly return the object they
initialize. To inform the caller when initialization has failed, an
Objective-C initializer can return nil. In Swift, this pattern is
built into the language feature called failable initialization. Many
Objective-C initializers in iOS and OS X system frameworks have been
audited to indicate whether initialization can fail. These
Objective-C initializers are imported as either init(...)—if
initialization cannot fail–or init?(...) if initialization can fail.
In your own Objective-C classes, and classes in frameworks that have
not yet been audited, initializers are imported as init!(...). For
example, the NSString(contentsOfFile:) initializer can fail to
initialize an NSString object if the file doesn’t exist at the
provided path. You can use optional binding to unwrap the result of
an failable initializer if initialization is successful."
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html
I'm going to take a stab at this even though this question has been around for a while because I think some example source code would be useful for understanding what init! is for (at least it was for me).
An implicitly unwrapped optional provides two things of value:
A convenience for the programmer (so you don't have to keep typing '?' at the end of your optional variables), and
Runtime efficiency because it allows you to test an optional for nil only once, and thereafter (as long as it is non-nil) use its unwrapped (i.e. direct) value.
The important part though is that an implicitly unwrapped optional is still an optional, which means it can be tested for nil.
Now, as to the utility of the init!-failable initializer, we can use it to get the two things I listed above (convenience and runtime efficiency), while still allowing an init function to fail (i.e. to return nil). This can happen, as others have noted, by calling into Objective-C API, but it can also happen directly from code you might choose to write. Here's an example:
class A {
init!() {
return nil // something happens that causes init to fail
}
}
var a:A! = A() // variable 'a' *is* an optional, and also nil
if a != nil { // and we can test it!
print( "a is not nil" )
} else {
print( "a is nil, better not use it." )
}
In this example, I gave myself a way to fail the initialization of class A, and yes, could as easily have done it with an init? method, but when I create an object of type A I'll probably only ever need to test that the initialization succeeded or failed once--after all, I either created an A or I didn't--and afterwards if it's not nil I'll just want to use the direct value. So in this case, using the init!-failable initializer turns out to be pretty handy.
It makes a difference in two situations:
If you write
let x: myclass = myclass(...)
then init? will not compile because init? returns an optional; init! will compile but crash if the init method returns nil.
If you write
let x = myclass(...)
then it will compile in either case, and it will not crash in either case. The difference is that in one case x has type myclass? and in the other case type myclass! with the obvious differences in behaviour.
If you write one of the following two:
let x: myclass? = myclass(...)
let x: myclass! = myclass(...)
then it doesn't matter whether init! or init? was used, because either can be assigned to an optional without crashing.
The init initializer is the same like the constructor for classes in other languages.
It sets initial values and performs some initial Operations (like checking wether a value is to big etc.).
Interesting: It also takes Parameters and can be overloaded.
Example:
struct Celsius {
var temperatureInCelsius: Double
init(fromFahrenheit fahrenheit: Double) {
temperatureInCelsius = (fahrenheit - 32.0) / 1.8
}
init(fromKelvin kelvin: Double) {
temperatureInCelsius = kelvin - 273.15
}
}
let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
let freezingPointOfWater = Celsius(fromKelvin: 273.15)
So when when you call the struct it returns different values depending on your call parameters.
For more info: http://www.informit.com/articles/article.aspx?p=2246797
I'm trying to switch from Objective-C to Swift.
I don't understand the point of declaring a function to return a AnyObject! instead of AnyObject?.
For example:
func instantiateViewControllerWithIdentifier(identifier: String) -> AnyObject!
Why does this method return an implicitly unwrapped optional and not a simple optional?
I get the AnyObject part, but what's the point of allowing us to avoid using the ! to unwrap the optional if it may be nil? (thus crashing the app, even if it's very unlikely)
What am I missing?
Is it just a convenient way to use the return value of this method without having to use ! or is there something else I can't see? In which case, is the program doomed to crash if it returns nil?
It sounds to me that:
AnyObject means 100% chance to return something
AnyObject? means 50% chance to return nil, you should always check for nil
AnyObject! means 99% percent chance to return something not nil, checking for nil is not required
Also, I assume there is some kind of link with Objective-C/NSObject classes, but can't figure out what...
Thank you
The frequency of implicitly unwrapped optionals (IUOs) in Cocoa APIs is an artifact of importing those APIs to Swift from ObjC.
In ObjC, all references to objects are just memory pointers. It's always technically possible for any pointer to be nil, as far as the language/compiler knows. In practice, a method that takes an object parameter may be implemented to never allow passing nil, or a method that returns an object to never return nil. But ObjC doesn't provide a way to assert this in an an API's header declaration, so the compiler has to assume that nil pointers are valid for any object reference.
In Swift, object references aren't just pointers to memory; instead they're a language construct. This gets additional safety by allowing us to assert that a given reference always points to an object, or to use optionals to both allow for that possibility and require that it be accounted for.
But dealing with optional unwrapping can be a pain in cases where it's very likely that a reference will never be nil. So we also have the IUO type, which lets you use optionals without checking them for nil (at your own risk).
Because the compiler doesn't know which references in ObjC APIs are or aren't safely nullable, it must import all object references in ObjC APIs (Apple's or your own) with some kind of optional type. For whatever reason, Apple chose to use IUOs for all imported APIs. Possibly because many (but importantly not all!) imported APIs are effectively non-nullable, or possibly because it lets you write chaining code like you would in ObjC (self.view.scene.rootNode etc).
In some APIs (including much of Foundation and UIKit), Apple has manually audited the imported declarations to use either full optionals (e.g. UIView?) or non-optional references (UIView) instead of IUOs when semantically appropriate. But not all APIs have yet been audited, and some that have still use IUOs because that's still the most appropriate thing for those APIs to do. (They're pretty consistent about always importing id as AnyObject!, for example.)
So, getting back to the table in your question: it's better not to think in terms of probabilities. When dealing with an API that returns...
AnyObject: always has a value, cannot be nil.
AnyObject?: may be nil, must check for nil
AnyObject!: no guarantees. Read the header, documentation, or source code (if available) for that API to find out if it can really be nil in your situation and treat it accordingly. Or just assume it can be nil and code defensively.
In the case of instantiateViewControllerWithIdentifier, there are two options you might call equally valid:
Say you're guaranteed to never get nil because you know you put a view controller in your storyboard with that identifier and you know what class it is.
let vc = storyboard.instantiateViewControllerWithIdentifier("vc") as MyViewController
// do stuff with vc
Assume your storyboard can change in the future and set yourself up with a meaningful debug error in case you ever break something.
if let vc = storyboard.instantiateViewControllerWithIdentifier("vc") as? MyViewController {
// do something with vc
} else {
fatalError("missing expected storyboard content")
}
AnyObject means it cannot be nil
AnyObject? and AnyObject! both mean they can be nil. There is no "probability" difference between them. The only difference between them is with AnyObject you don't have to explicitly force-unwrap it, for convenience. With both of them you can use optional binding and optional chaining if you want to use it safely.
Object pointer types in Objective-C are by default imported into Swift as implicitly-unwrapped optionals (!). That is because all Objective-C pointers could potentially be nil (there is no way to tell automatically from an Objective-C declaration whether a particular object-pointer can be nil or not), but maybe in a particular API it can't nil, so they don't want to burden you with explicitly unwrap if if this is the case.
Apple has been "auditing" its APIs to manually add information for whether each object-pointer type can be nil or not, so over time you will see AnyObject! in the API change to AnyObject or AnyObject?. This process takes lots of human effort and is slow and ongoing.
Regarding the following function declarations:
#1) func instantiateViewControllerWithIdentifier(identifier: String) -> AnyObject
#2) func instantiateViewControllerWithIdentifier(identifier: String) -> AnyObject!
#3) func instantiateViewControllerWithIdentifier(identifier: String) -> AnyObject?
#2 and #3 are logically the same, however, as per p 40 of The Swift Programming Language iBook, the answer is, much like Rickster's answer, a matter of semantics.
AnyObject! and AnyObject? are treated the same behind the scenes (they are initially set to nil and can be nil at any point), however it is the intention that once AnyObject! has been set it should no longer point to nil.
This allows one to avoid using the forced optional unwrapping syntax (!) and simply use implicitly unwrapped optionals (variables declared with !) to access the value contained within the assigned variable.
An example from the book:
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // no need for an exclamation mark
As applied to the above:
func instantiateViewControllerWithIdentifier(identifier: String) -> AnyObject! {
return nil
}
let optionalVC: AnyObject! = instantiateViewControllerWithIdentifier("myVC")
self.viewController.presentViewController(optionalVC as UIViewController, animated: true, completion: nil)
// The above is perfectly valid at compile time, but will fail at runtime:
// fatal error: unexpectedly found nil while unwrapping an Optional value
Thus, a function that declares the return value as AnyObject! can return nil however, should avoid doing so to avoid breaking the implied contract of implicitly unwrapped optionals
I've seen a lot of discussion regarding variables in Swift that are declared as var a: String? and var a: String! the former being an optional variable of type String and the latter being implicitly unwrapped optional String. From my understanding, when something is implicitly unwrapped there's an assumption being made that there's a value already included in the optional value. In order to use the syntax a!.toInt() there would have to be an outside check like so:
if a != nil {
a!.toInt()
}
As a side note, it seems better practice to just declare variables as an optional type and then use optional chaining to unwrap the value if it exists. Doing:
if let numberString = a?.toInt() {
numberString.toInt()
}
Is there a scenario in where accessing a variable like a!.toInt() should ever be used in practical applications? To me, it seems like you'd be asking for runtime errors.
Now for the actual question. I was looking through the documentation, specifically enumerateObjectsUsingBlock on NSArray and the block parameter is declared using an !. Does this mean that the writers of that function are assuming that the block parameter will be non-nil? If so, inside that function, what is the semantic difference between:
func someMethodWithBlock(block:((String!)-> Void)!) {
var a = "Hello"
block.(a) //first syntax example
block?.(a)//2nd
block!.(a)//3rd
}
Implicitly Unwrapped Optionals are used almost everywhere in the Cocoa APIs as they are imported into Swift — this is to maintain compatibility with the kind of pointer semantics that are ubiquitous in Obj-C, without requiring !s and ?s all over the place. That's why the NSArray method's block takes a String! argument.
In Swift, regular Optionals (Int?, etc.) are largely preferable for the reasons you specified: they are less prone to errors. Implicitly Unwrapped Optionals are mostly meant to be used only in certain cases, like when you need to pass self to a function before initialization is complete. (If you know a variable is not nil, unwrapping it like a!.toInt() is just fine. The danger with IUOs is that it would be written a.toInt(), and to a reader this looks completely safe, when in reality it's not.)