All posts by admin

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. :

create table cells using xib

https://medium.com/@musawiralishah/creating-custom-uitableviewcell-using-nib-xib-files-in-xcode-9bee5824e722#.lbixf1y87

New File > Empty Interface Builder
Then you’ll see the .xib file appear

create_xib

Click on the “right pane button” to make the Identity Inspector appear, because that’s where all the Interface Builder attributes are.
If the right pane button is not there, go to menu View > Utilities > Identity Inspector.

In the UI components section on the bottom, scroll through all of the UI components that you can drag and drop into the IB. When you get to “Table View Cell”, drag it into the empty space

drag_table_view_cell

Then drag a label across, and into the cell.
drag_in_label

Create a UITableViewCell source file. In order to connect source file to interface builder, first make sure our cell is selected. Then enter the existing class’s name into the “Custom Class” textfield of the Identity Inspector.

Click on the small arrow button to make sure the xib can detect and navigate to the correct source file. Once that’s done, double click your xib so it opens. Then open up the hierarchy of UI components and you can ctrl+drag the components into the registered source file.

xib_class_name

Next, we will create outlets for the text labels in our cell so we can set their values.

You will see the IB outlet in your code like so:

to the left of the code, in the region where you put your breakpoints, you’ll see a small circle. If you hover over that circle, you’ll see that the corresponding UI component in IB will light up.

xib_corresponding_ui

As you can see, both says noteLabel.

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.