Why do some UIKit functions return implicity unwrapped optionals? - uikit

I'm looking at some of the UIKit headers in Swift, in particular the one for UIViewController and there's a couple of functions that return implicity unwrapped optionals rather than plain optionals.
For example:
// The rotating header and footer views will slide out during the rotation and back in once it has completed.
func rotatingHeaderView() -> UIView! // Must be in the view hierarchy. Default returns nil.
func rotatingFooterView() -> UIView! // Must be in the view hierarchy. Default returns nil.
Default value they're returning is nil. Surely returning plain optionals would be better in this case to let the developer know that what's being returned is very likely to be a nil value?

Implicitly unwrapped optionals are the best match for the objects we used (past tense, amirite?) in Objective-C. They let you both use the returned value directly (without needing optional operators ? or !) but still query them for nil value.
For more see Rob Napier's great answer to a related question.

Without reading into the minds of the language authors, it's hard to say for certain why some UIKit functions return implicitly unwrapped optionals.
Presumably, these functions do contain a value (are non-nil). So one reason why the optional is used, explicitly unwrapped, could be to make it possible to allow type checking through optional binding:
if let definiteString = assumedString {
println(definiteString)
}

Related

Xcode:(user defined runtime attribute)Range with minus value. Alternative?

I made a custom UITextField with an additional user defined runtime attribute validRange, which I can set in the storyboard view.
I use this property to check in the EndEditing method to validate the new set text.
I works all fine, till I had to set a valid range from {-100,100}
As NSRange uses NSUInteger, there are no minus values possible.
What is the best way to still make this happen?
Would it be acceptable if I use CGSize instead of NSRange?
Updated Content
Xcode only gives me the following choice of data types for the user defined runtime attributes:
This means I cannot define a new struct to create a CustomRange with NSInteger.
As Point,Size are both {NSInteger,NSInteger} data types, I thought about using them. But this would be certainly a misuse, so I am wondering if someone knows a better solution, as misusing Point or Size to get this to work.
As another workaround I could user String, which I manually would split up in a method of the custom UITextField, but then there is no type safety.
Then I would suggest you to define two NSNumber properties with suitable names to represent NSRange value instead of abusing CGSize as using CGSize confuses other readers/programmers as we there is a saying, we code for others not for ourselves.
And there is a NSNumber class method as follows
+ (NSNumber *)numberWithInteger:(NSInteger)value
which allow you to wrap signed integer value as you intend.

Adding a stored property to a subclass of NSManagedObject in Swift

If I try to add a stored property to a subclass in NSManagedObject in Swift, without providing it with a default value (I'll do that in an initialiser, mind you), I get this error:
Stored property 'foo' requires an initial value or should be #NSManaged
The code is as follows:
class Thing : NSManagedObject{
var foo : String
var bar : String
init(foo: String, bar : String){
// blah, blah...
}
}
What's the reason for enforcing this? Why the heck can't I initialise in an initialiser????
EDIT: The below answer applies to a wide variety of situations, and is related for this, but does not exactly address the NSManagedObject situation. In the case of NSManagedObject, an object can be loaded from the persistent store and initialized without calling your special init. Swift doesn't know what it should assign foo and bar in those cases, so requires some default values (rather than just using final or required as you could do in other subclassing situations cases).
So the correct question is: what would you expect Core Data to do with foo and bar when it loads this object out of the data store?
Because the compiler cannot prove that all subclasses will implement or call init(foo,bar). If a subclass did not implement that initializer, then foo or bar may not be initialized.
You can resolve this many ways. You can provide defaults. You can make the values explicitly unwrapped optionals (making their default nil). You can make the values optional. You can declare this initializer required so that all subclasses must implement it. Or you can declare Thing to be final so that it cannot be subclassed.

NSThread: Selector not found

I'm a bit confused why my NSThread cannot be instantiated using a selector due to a runtime error
target does not implement selector (*** -[FileSearcher processFilesAsync:])
The function is defined like this
func processFilesAsync(#data: [String])
and the NSThread will be created this way:
NSThread(target: self, selector: "processFilesAsync:", object: itemsPerThread[i])
"itemsPerThread" is just a dictionary with a String-Array as values.
As far as I know this should work as the method I want to invoke defines an argument and the selector I pass into NSThread's init() method indicates that the target method expects exactly one argument.
I already tried using Swift's "Selector" type instead of only a string but this didn't work as well. I also tried to change the method's type from "[String]" to "AnyObject" which didn't work, too.
Does anybody have a clue what might be wrong?
All of the code above lies within the same class.
I'm using Xcode 6 Beta 5.
Edit
I figured out that is has to do something with the parameter. I implemented a dummy method without parameters and tried to set this as target and it worked. As soon as I modified it to use a parameter as well -> same as above.
Found it. All I had to do was to change the parameter's type from AnyObject to AnyObject?. It even works with specialised types (in my case [String]? instead of [String]).
Of course, because you can call it nil as parameter...

Get a CGImageRef from an IKImageView in Swift

I'm trying to get the image associated with a view but Xcode returns me an error. Here is the code:
#IBOutlet var imageView: IKImageView // Link to the image view.
func saveImage() {
var newImage: CGImageRef = imageView.image() // Line with an error.
}
I have a awakeFromNibfunction to set the image in the view. The code above returns me 'Unmanaged<CGImage>' is not convertible to 'CGImageRef'.
I know that types are optional in Swift but I don't understand why I get this error, the IKImageView Class Reference clearly said that get IKImageView's image return a CGImageRef.
This has to do with the bridging of Objective C APIs into Swift. The Swift versions of an API have been bridged (mostly automatically, I believe) by converting the original Objective C headers into a Swift version. In many cases, the conversion can work out what kind of value you're going to get back, and therefore in Swift you get a "normal" type that you can use as you'd expect.
However, the conversion is still a work in progress. In this case, what you're seeing is a type used to help you manage memory manually when the conversion process doesn't know whether you're going to get back an object that's been retained for you or not, because the API doesn't have the conventional annotation that it could use to figure it out.
The Unmanaged type effectively says "you have to tell me what to do with the contained value to get the memory management right". As soon as you get an Unmanaged value, you should call either one of its two methods:
takeUnretainedValue()
takeRetainedValue()
...depending on whether the object you get back was a "+0" or "+1". So, you're expected to do something like:
var newImage: CGImage = imageView.image().takeUnretainedValue()
And as soon as you've done that (which you should do pretty much immediately), you've given Swift enough of a hint that it can now appropriately manage the object correctly with ARC, and got yourself a valid reference of the right type.
This is touched on briefly at the end of the "Swift Interoperability in Depth" WWDC video from this year.
Look at the image() method in the new version of the IKImageView reference that shows Swift declarations and you'll see it returns an Unmanaged<CGImage>!. That means that ImageKit isn't set up such that the compiler can automatically infer CoreFoundation memory management semantics on its API. (This affects both Swift translation and ObjC implicit ARC bridging.) It should, so that'd be a good bug to file.
The Swift type Unmanaged<T> is how you interact with CF types when the compiler can't automatically infer their ARC behavior. To get at the underlying type, call either takeUnretainedValue() or takeRetainedValue() — you have to choose which depending on whether the API you're calling is known to already be retaining the value it returns. Exciting guesswork! (Again, eliminating guesswork would be a good bug to file.) You can read more about this in Using Swift with Cocoa and Objective-C.
Anyway, in this case you can probably expect that IKImageView is not incrementing the retain count of the CGImage when providing it, so you can unwrap the Unmanaged like so:
var newImage: CGImage = imageView.image().takeUnretainedValue()
Also note you don't need the Ref suffix when working with CF types in Swift. (CGImageRef is a typealias to CGImage.) Swift lets you work with CF types as if they're Swift objects (instead of as C pointers to opaque C types).

Why are receivers pass by value in Go?

Seems like you'd ALWAYS want this:
func (self *Widget) Do() {
}
instead of this
func (self Widget) Do() {
}
If so, then the way to get the former semantics OUGHT to be by using the latter syntax. i.e. receivers ought to be pass by reference.
It is because everything in Go is pass by value. This makes it consistent with other C family languages, and means that you never need to remember whether the situation you're looking at is pass by value or not.
From that link:
As in all languages in the C family, everything in Go is passed by value. That is, a function always gets a copy of the thing being passed, as if there were an assignment statement assigning the value to the parameter. For instance, passing an int value to a function makes a copy of the int, and passing a pointer value makes a copy of the pointer, but not the data it points to. (See the next section for a discussion of how this affects method receivers.)
Then later:
func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct) valueMethod() { } // method on value
For programmers unaccustomed to pointers, the distinction between these two examples can be confusing, but the situation is actually very simple. When defining a method on a type, the receiver (s in the above examples) behaves exactly as if it were an argument to the method. Whether to define the receiver as a value or as a pointer is the same question, then, as whether a function argument should be a value or a pointer. There are several considerations.
First, and most important, does the method need to modify the receiver? If it does, the receiver must be a pointer. (Slices and maps act as references, so their story is a little more subtle, but for instance to change the length of a slice in a method the receiver must still be a pointer.) In the examples above, if pointerMethod modifies the fields of s, the caller will see those changes, but valueMethod is called with a copy of the caller's argument (that's the definition of passing a value), so changes it makes will be invisible to the caller.
By the way, pointer receivers are identical to the situation in Java, although in Java the pointers are hidden under the covers; it's Go's value receivers that are unusual.
Second is the consideration of efficiency. If the receiver is large, a big struct for instance, it will be much cheaper to use a pointer receiver.
Next is consistency. If some of the methods of the type must have pointer receivers, the rest should too, so the method set is consistent regardless of how the type is used. See the section on method sets for details.
For types such as basic types, slices, and small structs, a value receiver is very cheap so unless the semantics of the method requires a pointer, a value receiver is efficient and clear.
Sometimes you don't want to pass by reference though. The semantics of
func (self Widget) Get() Value {
}
Can be useful if for instance you have a small immutable object. The caller can know for certain that this method doesn't modify it's reciever. They can't know this if the reciever is a pointer without reading the code first.
To expand on that for instance
// accessor for things Config
func (self Thing) GetConfig() *Config {
}
Just by looking at this method I can know GetConfig is always going to return the same Config. I can modify that config but I can't modify the pointer to Config inside Thing. It's pretty close to a const pointer inside of Thing.
Seems like you'd ALWAYS want this:
No. The value receiver is more general. It can be used in all the places that a pointer receiver can; but a pointer receiver cannot be used in all the places that a value receiver can -- for example, if you have an rvalue expression of the type Widget; you can call value-receiver methods on it, but not pointer-receiver methods.

Resources