Category Archives: Uncategorized

Optionals, non-optionals, implicit unwrapped optionals for return types

http://stackoverflow.com/questions/30068200/returning-an-unwrapped-optional-in-swift

http://stackoverflow.com/questions/24728235/why-do-objective-c-apis-return-implicitly-unwrapped-optionals?rq=1

Implicitly unwrapped optional is basically an optional, that gets an ! everywhere you use it. Thats it.
e.g.:

is the same as this:

An implicitly unwrapped optional is only to save you the need of unwrapping it every time you use it, wether with if let or with an !, but it has the same optionality of being nil as a normal optional.

An implicitly unwrapped optional is still an optional – it could be nil. If you simply write self.device.hasFlash, when self.device is nil, you will get an exception.

When you make an implicitly unwrapped optional in Swift, it does not mean that it is always going to be non-nil: all it means is that you tell the compiler that when you access their properties, you expect the object to be non-nil. The object that you reference can be explicitly checked for nil; setting it to nil will not cause an exception either, unless you try to access any of its properties after that.

When Apple used implicitly unwrapped optionals for the parameters of

function, they let you save on a few extra if – let. In this case, they know that they never pass you a nil; in other cases, they do not know it, and they expect you to nil-check the object.

They allow you to return nil, too. It is up to them to check the results for nil, unless, of course, you decide to call that function yourself. Although I cannot think of a valid reason to call cellForRowAtIndexPath from your own code, if you do make a call, it would be your responsibility to check the return value for nil.

example

you can check like so:

What if we used ?

If you consider an alternative of making the parameters UITableView? and NSIndexPath? instead, all implementations would have to either use an exclamation point after tableView and indexPath, or use the if – let idiom. Compared to this choice, implicitly unwrapped types look like a better choice.

Sample

If we change the temp variable to implicit optional, everything is same, because after all, we are dealing with an optional. However the characteristics involved is that we don’t need to use if-let. The variable is “implied” that we want to unwrap it.

Now, we use an implicity unwrapped Optional, hence, we simply use temp in the print function for its unwrapped value.

Another thing to notice is that let t is an optional. Thus, as an optional, you still need to force unwrap it to get the value.

Returning a Optional or Implicit Unwrapped Optional does not matter. What matters is whether the variable taking on the return value is of Optional or Implicit Optional.

Optionals, and Implicit Unwrapped Optionals function parameters

ref – http://chineseruleof8.com/code/index.php/2017/02/01/swift-3-0-constants-and-variables/

Non-optional parameters

1) You cannot force unwrap a non-optionals. There’s nothing to unwrap because it is not an optional.

2) You cannot use optional chaining on non-optionals variables because optional chaining can only be done on optional variables

3) You CAN use the non-optional variable as is:

result:

ricky

Optional parameters

1) You CAN use force unwrap, as it means you are sure that the optional is non-nil, and you are using a short-hand to unwrap it.

In other words, Optional is an enum where its two attributes are None, and Wrapped(your value). By using ‘!’, you are unwrapping the value object.

2) You CAN use ‘?’ on the parameter to indicate that you want to use optional chaining. Optional Chaining is simply a way for you to chain access of the Wrapped object and call a property or method on it.

In other words, Optional is an enum where its two attributes are None, and Wrapped(your value). By using ‘?’, you are accessing Wrapped(your value), and thus be able to get to the Wrapped(..)

However, you still need to access the object/value inside that Wrapped, and that’s why you have to use ‘!’ on the outside.

3) You cannot simply use the parameter like this. Optional parameters need to be unwrapped before you can access its value object.

asis_on_optional

Implicity Unwrapped Optional parameters

You CAN use the parameter name as is because implicit unwrapped optional means you are sure it is not nil.

present view Controller (with xib)

where MainInterface is the string name of the storyboard file
and SearchDisplayViewController is the id of the view controller created in the storyboard.

present view controller programmatically (non-xib)

where SearchDisplayViewController is your (non-xib, code only) custom view controller. :

computed property vs stored property (swift)

http://stackoverflow.com/questions/31515805/difference-between-computed-property-and-property-set-with-closure

Swift: Beware of Computed Properties

The computed property’s block is called each time you reference the variable

Computed Property:

Stored Property

ASSUMING THAT YOU DO NOT set the stored property, the stored property’s initialization closure is called once and only once when you do the first READ. Any other READS after that will simply return the variable itself. Thus, it is useful for setting default values.

In other words, (granted you do not set it) it is calculated only when the variable is accessed for the first time. Then, it simply just returns the variable.

However, if you were to set the stored property, the initial closure will not be run, and it will simply access the variable
for you to use:

Now let’s test it. As you can see, if you READ the property name for the first time, the lazy load will be called. Every READ after that will be a direct access and it won’t call the function anymore.

output:

—-init Test class—–
— load data for stored property ‘name’ —
Ricky
Ricky
Hannah

Simply using SET will not call the closure

When the property ‘name’ is set explicitly, it doesn’t do the lazy loading.

closures in swift

ref – https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html

Chapter 9: Closures


http://alisoftware.github.io/swift/closures/2016/07/25/closure-capture-1/

functions and closures are reference types

Closures are reference types. This means that when you assign a closure to more than one variable they will refer to the same closure. This is different from value type which make a copy when you assign them to another variable or constant.

Whenever you assign a function or a closure to a constant or a variable, you are actually setting that constant or variable to be a reference to the function or closure.

say incrementByTen is a function, we assign constant alsoIncrementByTen to it like so:

Closures can capture and store references to any constants or variables from the context in which they are defined.
In Swift, closures capture the variables they reference: variables declared outside of the closure but that you use inside the closure are retained by the closure by default, to ensure they are still alive when the closure is executed.

Declaring a closure

The general syntax for declaring closures is:

If the closure does not return any value you can omit the arrow (->) and the return type. This also applies to the case where the type of the closure can be infered.

Capturing Values

In Swift, closures capture the variables they reference: variables declared outside of the closure but that you use inside the closure are retained by the closure by default, to ensure they are still alive when the closure is executed.

In the below example, say we declare an object Pokemon. We delay 1 second, so that this function finishes running and exits. Then we see that closure of delay function will fun “closure()”.

That’s because the closure strongly captures the variable pokemon: as the Swift compiler sees that the closure references that pokemon variable inside the closure, it automatically captures it (strongly by default), so that this pokemon is alive as long as the closure itself is alive.

In this example, the closure itself gets released once it has been executed by GCD, so that’s when the pokemon’s deinit method gets called too.

IF Swift didn’t capture that pokemon variable automatically, that would mean that the pokemon variable would have had time to go out of scope when we reach the end of the demo1 function, and that pokemon would no longer exist when the closure would execute one second later… leading to a probable crash.

Captured variables evaluated on execution

If we have a closure that captures a pokemon variable, and that variable points to a first Pokemon instance, then a second Pokemon instance in the closure’s context, after the function exits, which pokemon instance will the closure reference?

result:

We print the new pokemon, not the old one! That’s because Swift captures variables by reference by default.

So here, we initialize pokemon to Pikachu, then we change its value to Mewtwo, so that Pikachu gets released — as no more variable retains it. Then one second later the closure gets executed and it prints the content of the variable pokemon that the closure captured by reference.

The closure didn’t capture “Pikachu” (the pokemon we got at the time the closure was created), but more a reference to the pokemon variable — that now evaluates to “Mewtwo” at the time the closure gets executed.

  1. Pickachu was created
  2. then the closure only captured a reference to the pokemon variable, not the actual Pickachu pokemon/value the variable contained.
  3. So when pokemon was assigned a new value “Mewtwo” later, Pikachu was not strongly referenced by anyone anymore and got released right away.
  4. But the pokemon variable (holding the “Mewtwo” pokemon at that time) was still strongly referenced by the closure
  5. So that’s the pokemon that was printed when the closure was executed one second later
  6. And that Mewtwo pokemon was only released once the closure was executed then released by GCD.
Capturing a variable to use in a closure as a constant copy

If you want to capture the value of a variable at the point of the closure creation, instead of having it evaluate only when the closure executes, you can use a capture list.

Capture lists are written between square brackets right after the closure’s opening bracket (and before the closure’s arguments / return type if any)3.

To capture the value of a variable at the point of the closure’s creation (instead of a reference to the variable itself), you can use the [localVar = varToCapture] capture list. Here’s what it looks like:

You can modify captured values in closures

Note that if the captured value is a var (and not a let), you can also modify the value from within the closure2.

This code prints the following:

Essentially, this is what’s happening:

Pikachu is referenced a constant pokemonCopy.

Here’s what happens:

  1. Pikachu is created
  2. then it is captured as a copy (capturing the value of the pokemon variable here) by the closure.
  3. So when a few lines below we assign pokemon to a new Pokemon “Mewtwo”, then “Pikachu” is not released just yet, as it’s still retained by the closure.
  4. When we exit the demo6 function’s scope, Mewtwo is released, as the pokemon variable itself — which was the only one strongly referencing it — is going out of scope.
  5. Then later, when the closure executes, it prints “Pikachu” because that was the Pokemon being captured at the closure creation’s time by the capture list.
  6. Then the closure is released by GCD, and so is the Pikachu pokemon which it was retaining.
Capture global context

In the beginning of the chapter I mentioned that closures can capture values. Let’s see what that means:

So a closure can remember the reference of a variable or constant from its context and use it when it’s called. In the example above the number variable is in the global context so it would have been destroyed only when the program would stop executing.

closure captures a variable that is not in the global context

custom tableview and cell in swift

UITableView and delegates

  • create cellReuseIdendifier for cell string reuse id
  • set up tableview and its delegates, implement delegate methods
  • tableView.register(YourCell.self, forCellReuseIdentifier: “”)
  • in cellForRow, tableView.dequeueReusableCell(withIdentifier: cellReuseIdendifier) as! SearchDisplayTableViewCell

UITableViewCell

difference between ? and !

ref – http://stackoverflow.com/questions/24083842/what-is-the-difference-between-string-and-string-two-ways-of-creating-an-opti

Use ? if the value can become nil in the future, so that you test for this. variables with ? will degrade gracefully if nil.

Use ! if it really shouldn’t become nil in the future, but it needs to be nil initially. If the variable is nil and you use exclamation, it will crash.

Protocols in swift

http://stackoverflow.com/questions/24024466/how-do-i-make-a-class-conform-to-a-delegate-in-swift

Learn Swift from Objective-C : Protocols and Delegation

Defining a protocol

Conforming to protocol

Delegate it

To create a delegate in obj-c, it uses id to mean that this class can be of any type,
as long as it conforms to some protocol in the “<" ">” bracket. The variable name is delegate.

in swift, it is simply declaring an optional variable called delegate of type SampleProtocol.
That way, it can show that its valid or nil.

The variable is of any type by default.

Using your delegate

if you delegate is connected, using the protocol function will not be nil. If your delegate is not connected and is nil, then delegate?.YourFunc() will return nil

Optional protocol functions

http://stackoverflow.com/questions/24032754/how-to-define-optional-methods-in-swift-protocol

If you want to declare optional functions in your protocol, you must declare @obj keyword in your protocol declaration. You must ALSO declare @obj keyword in front of your optional function

Remember to declare the required protocol functions in your class. If not, you’ll get a compiler error to remind you to do so:

swift_required_protocol_function

Object type of the delegate

Swift’s var is not Objective-C’s id

In swift, a variable can be of any type. Its type is set when you assign it to an object.
Thus, in swift, you do not need to specify id, as you did in objective c.

Swift’s var vs Obj-C’s id

Swift is a statically typed language, so once a variable (var) is defined, the type of that variable will remain the same forever. With id in Objective-C, that’s not necessarily the case.

In Swift, once a variable is defined, you can’t change its type. However, an obj-c id can switch around.

This illustrates the difference between Swift and Objective-C, or in a more general sense, the difference between statically typed and dynamically typed languages.

Let’s look at the definition of those words: “static” and “dynamic”. Starting with “static”, courtesy of the Dictionary in OS X:

“lacking in movement, action, or change”
So if calling something static means that it lacks movement, action, or change, then saying a language is statically typed means that its types cannot change. And that’s what we have in Swift.

Contrast this with “dynamic”:

“characterized by constant change, activity, or progress”
Sounds a bit like Objective-C’s id type, right? Its type is contantly changing, or at least, it can be changed constantly, as we did in the example above.

“But wait,” you may be thinking, “Swift’s var is constantly changing, too – it’s just like Objective-C’s id.” And you’re half-right – we can do the following in Swift:

So it looks like var is constantly changing – sometimes it represents an Int, sometimes a String. But the type of the variable never changes – our a is always an Int, and our b is always a String. And remember our previous example, where we tried to change x from 1 to “hello” and the compiler screamed at us. Once a variable’s type is set in Swift, it’s set. It can’t change. And that’s what static typing is.

So that brings us to another question: how is a variable’s type set in Swift? Let’s look at our previous Swift example again:

The error from the compiler (on line 2 above) gives us the type. The error says (in Xcode 6 Beta 4):

Type ‘Int’ does not conform to protocol ‘StringLiteralConvertible’
So we can conclude that Swift has inferred the type of x – it’s an Int, and we didn’t call it one. This is known as type inference, and it’s one nice feature in Swift that’s not in Objective-C.

Let’s look at the definition of the word “infer”:

“deduce or conclude (information) from evidence and reasoning rather than from explicit statements”
Swift uses type inference to conclude that our little x is of type Int, even though we didn’t explicitly state that x should be an Int. And then it prevents us from changing x to a String since Swift is statically typed. This is in stark contrast to Objcetive-C, which requires explicit types and is dynamically typed.

Swift’s var is decidedly not Objective-C’s id – it’s just a keyword we use to state that we’re creating a variable. That variable’s type is inferred by the compiler via a feature called type inference, and once that variable has a type, it always has that type. Once an Int, always an Int.

In Swift 3, the id type in Objective-C now maps to the Any type in Swift, which describes a value of any type, whether a class, enum, struct, or any other Swift type.