Porting Swift & Objective-C (Part – 2)

This part will focus on the syntactic and logical overview of some more complex parts of Swift and Objective-C. If you have stumbled upon this and want an insight of some basic concepts of both the languages, I would encourage you to read the “Part-1” of this article first. In this part we will go through the contexts of the following components:

  • Optionals
  • Casting
  • Closures / Blocks
  • Delegates / Protocols
  • Retain Cycle

a.) Optionals

Optionals is more of a Swift centric approach. In fact, it is inclined 80% towards Swift. The thumb rule is, your variables should not be nil before you use them. If they are nil, it should not impact your code, via appropriate checks or error handling.

Swift is one step more strict about the nil values. While creating optional variables, we box them up like a present and unwrap them before usage. Let’s see a simple example:

optional1

 

Here we see the implementation in Objective-C and Swift (Left to Right)

In Swift, whenever we write a variable, we must provide some value to it or else, mark it as optional by using the “?” operator.

var anOptional: String?

This line signifies that the variable named “anOptional” might or might not have a value in it. If we try to use this variable before providing any value to it, the app will crash. Hence the print statement (#1), crashes the app and the code flow will never reach the next line. Notice the “!” keyword, print (anOptional!)? It is used to force unwrap the variable which was boxed using the “?” operator. Here we deduce one more concept which says, only force unwrap variables, when you are absolutely sure that it will have a non nil value.

Moving on to the Objective-C controller, the NSLog statement (#1) won’t crash the app (that’s the reason, when I said Swift is one step strict than Objective-C). But If you try to add this variable to an array, it will crash. So I guess, if Objective-C could also provide a safety check at #1 only, the developer could identify the reason for a bug pretty early. Of course here we have a very trivial example but in real life scenarios, this could really creep up into your code and hurt the architecture later on.

The next thing on your mind would be how to fix this? The answer is very simple, just like you use try catch to handle a probable crash, here you need to check the sanctity of the variable before consuming it. Let’s see an example:

optional2

In Objective-C, its very obvious as Objective-C does not provide any particular syntax for it. Therefore, you simply check it with an if statement.

if (anOptional){

//Consume the variable

}


In Swift, however there are multiple ways to handle nil values. One of them is using the if-let statement also known as Optional Binding.  

if let someOptional = anOptional {

           print(“#1 “+someOptional)

       }

       else{

           //Handle nil here

       }

The important thing to notice here is, we create a temporary variable named someOptional and assign it to anOptional, if it contains a value, it will go inside the if  block and print out the statement otherwise it will go inside the else statement.

The scope of someOptional will be there for the if block only, that’s why you can see the use of someOptional twice in the same scope.

First time, the else block will be executed and second time, we assigned a value to anOptional so the if block will be executed and the output would be “#2 Now I have the value”.

Another category of optional binding is to use the guard statement. This is used to break out of the scope if the condition does not satisfy. You would normally want to use it during the validation of the data in a user form containing fields like firstname, lastname etc. Let’s see an example:

optional3

Here we have called a function named validateFormData() which will check if firstname and lastname optional strings are not empty. If you remove the return statement from the else blocks, you’ll get this error “guard’ body must not fall through, consider using a ‘return’ or ‘throw’ to exit the scope”. The compiler clearly says, we must use return statement or use throws to abort the further execution in order to satisfy the guard statement.

Optional Chaining: The basic concept of Optional chaining is, anything nil before the “?” operator, would not let the code to execute further thereby preventing the scope of errors. For instance, if we have a hierarchy of two classes namely, Parent and Child and we need to access the name of the child from the parent class, we would do something like this:

parentObject?.childObject?.name

Here all three objects are optionals and might or might not have a value. To end the scope of any errors, we use the “?” operator. If any of these objects are nil, the execution of this line won’t result in an error. If we don’t use this, we would end up in some thing called the doom of if-let pyramid.   

       if let testParent = aParent{

           if let testChild = testParent.child{

               if let name = testChild.name{

                   print(name);

               }

           }

       }

Here we are going step by step to check the validity of data for parent then for the child. This can be done in a single line of code, which is known as Optional Chaining:

if let name = aParent?.child?.name{

           print(name)

       }

 

b.) Casting

As the name suggests, Casting is a way of explicitly interpreting a data type. Lets see a quick example to understand this.

casting1

Here we have added an object of type Button and DatePicker to an array named anArray. Swift has more than one way of doing this so let’s quickly see the Objective-C one and then we’ll move to Swift.

The generic object type for all the object types in Objective-C is “id”. We can simply do a for-each loop over the array and then check if the current iteration matches to the one we want. Here we are looking for UIDatePicker object by using the isKindOfClass method available to every object type. If it passes this condition we can then use the round brackets and * symbol to convert our item object to the designated type.

(DataType *) targetObject

In Swift, as we have seen that its is one step more strict than Objective-C, we need to make use of optionals and force unwrapping to achieve casting.

#1 Force downcasting:
This is viable when you know that the target object is of the type, you are downcasting it to. We use the “is” keyword to first get the confirmation and once we have it, we use the “as!” keyword to force downcast it.

#2 and #3 Optional Downcasting:
Both of these options are a way of optionally downcast. Here we do not confirm the type via the “is” keyword. Therefore we need to optionally bind for every iteration, in order to prevent errors. We iterate through every object and try to optionally downcast to DatePicker. If it is successful we then access the property of DatePicker.

c.) Closures in Swift & Blocks in Objective-C

 

Closures or Blocks are self-contained blobs of functionality. They are very effective in information handoffs and passing around data in between your code architecture. They are a very crucial part of communication pattern in both the languages, considering the communication being one to one. Let’s not dive into the theory much but rather see a very basic implementation first.

closure1

I have used two blocks/closures with same implementation in both Objective-C and Swift side by side (Left to Right).

Swift: myClosure() and addTwoNumbers()

ObjectiveC: myBlock() and addTwoNumbers()

 

Here is a generic syntax verbiage of the two:

Block: (returnType) (^blockName)(parameter1, parameter2);

Closure: closureName: (parameter1, parameter2) -> (returnType)

If you see closely, there is not much difference between the two. The problem is, the syntax is not what you would write regularly so it’s a bit off the top to remember. I myself, use this post many times, to go back refresh the whereabouts of the syntax.

myBlock and myClosure have the exact same output i.e the print statement and so it is for addTwoNumbers. The Caret(^)  symbol is somewhat Objective-C legacy syntax, Swift does not have any such symbol to represent the closure.

By now you must feel that closure/block is nothing but a variable/property? Yes you are right. I like to define them as, Blocks/Closures are variables of type functions.

These are first class citizens, meaning they are reference types. If that’s true, you can imagine, if they are reference types then they can be passed around in a function or a parameter as well? Yes, you can do that. This is the most optimal usage for both of these. Imagine when you call a web service with the help of a method, in a separate singleton and reusable class. When the API comes back with a response, you must get the control of code from where you called it right? In that case we can pass a closure or a block to this web service method, so that it can call that closure/block back in the class from where it was originated from. Let’s see a bit complex example for passing a closure to a function.

closure2

The above image showcases the use of Blocks and Closures in Objective-C and Swift respectively (Left to Right).

 

The red boxes represent how you declare, define and call blocks/closures.

The blue ones represent how you call a method, passing these blocks/closures as parameters. This is useful, when you want to reuse them for multiple methods. So no matter how many times you pass this block as a parameter, the code control will always land in the red boxes with print statements. (4. API returned with status code:).

The green ones represent a more dynamic approach where we can call this method with an inline defined block/closure and we can have a different implementation every time we call this method. The code control will come back to the green boxes, once we call the block/closure.

The method to which we are passing a block/closure is callSomeAPIWithBlock/Closure: . This method takes a block/closure as parameter named completion. This block/closure in turn takes an integer as a parameter and returns nothing.

The basic idea is to mimic a method, which will call an API and will return the statusCode from the response(we are using a hardcoded statusCode to avoid the long API call and parsing code).

Since the name of the parameter is completion. We use that to call the block/closure back by sending the apt parameters required, which in this case is just an integer value, completion(200).

The output of both the methods would be:

  1. Start an async API call.
  2. It will return after getting the data from a web service.
  3. Now call the closure/block to inform the caller of this method.
  4. API returned with status code 200

 

d.) Delegates or Protocols

Delegate is also a part communication pattern in Swift and Objective-C and similar to blocks/closures they are designed to work with one to one relationships. The analogy is kind of a master and a slave dictatorship. Master will send orders for slave and the slave will inturn do the job without asking any questions. Most of the time you will use this pattern as a one to one communication between two entities.

We all have implemented TableView or CollectionView and their delegates as well. Let me ask you this, the controller in which you implement the delegates, have you ever thought of modifying them or changing their parameters? No, hence the master slave analogy.

Lets see how is it done in Objective-C first.

delegate1

This is how you declare a delegate. It’s in the MasterViewController.h only. Use @protocol keyword to tell the compiler that we are writing a delegate and use @end  to end its declaration. You can create any sort of method, which you want the slave to perform. If some methods are optional use the @optional/@required keyword. If you don’t mention optional/required, by default it is @required. It won’t crash your app, unless you try to invoke that method, without implementing it in the Slave.

@property (nonatomic, weak) id <MasterTasksDelegate> actionDelegate;

This property will be used by Slave or any other Class to assign itself as the target for the orders from Master. Always maintain a weak relationship from a parent to a child to prevent retain cycles (The image only has nonatomic, you can ignore that typo. It should be nonatomic,weak). Confused about retain cycles? Read the next point #C.

Above two are .m files of Slave and Master (Left to Right).

There is not much to do in Master now. We just need to check, if the actionDelegate is there and it respondsToSelector named performDailyChores. Once this condition is
passed (checking, if there is actually a slave present to listen to the orders), just call the performDailyChores method on actionDelegate  and it will be invoked in the SlaveViewController.

delegate2

 

Slave acts as the point of initiation where it accepts to take orders. This is done by just assigning the actionDelegate to itself (check the method, getOrdersFromMaster). Also, if you notice closely you’ll see we have used <MasterTasksDelegate> just after the interface declaration of SlaveViewController. This is called as “adopting the delegate”. The last thing which is required in Slave is actually implementing the order/methods from Master. Hence the performDailyChores, is being implemented in Slave only.

 

Let’s move on to SWIFT now…

delegate3

Above images are Slave and Master viewcontrollers.swift files (Left to Right). The methodology is same, slave will start the initiation to take orders from master, and master will inturn invoke those orders at some point of time. The only difference is syntax, let’s go through it.

Likewise Objective-C, you use the protocol  keyword to declare the MasterTasksDelegate in Master. We use “: class” keyword, to make our delegate to be limited to class types only or making our delegate to be a class-bound type. No struct type can adopt this delegate now. This is only required when we mark our variable as weak. But that is necessary to prevent retain cycles.

Unlike Objective-C, where we used the if-else blocks to check if the actionDelegate was available or not, we use Optionals (actionDelegate?.performDailyChores()) in swift. It’s more readable, concise and practical. Anything nil before a question mark symbol, will not let the code execute further, preventing any runtime issues.

In our Slave, we need to assign the actionDelegate to itself, this will allow the slave to take orders from Master. In order to adopt a delegate in Swift, we can use the extension keyword, this provides good readability and distribution in the code. Syntax is also somewhat similar to Objective-C:

 

extension SlaveViewController:MasterTaskDelegte {

}
If you have implemented any other delegates for tableViews, collectionViews, etc, you would know this already. Inside this extension, we can define all of our methods/orders from master. In Objective-C, you can use #pragma mark – to achieve this. This is an imperative part of code readability and distribution.

 

e.) Retain Cycle

If you have gone through the above two points, this one would be fairly easy. Delegation and Blocks/Closures are two types of calling patterns which can create retain cycles in your architecture. You already know how to avoid a retain cycle for Delegates. Let’s see how it is done for Blocks/Closures. But first some background about retain cycles.

What is a Retain Cycle?
When two entities keep a strong reference to each other and not letting any of them to go out of memory, this scenario is called a retain cycle.

For instance, a Parent class has the object of a Child class and it points strongly to that object. Similarly, Child also refers to parent strongly.
Now when the time comes, and the parent is done with all the work, it won’t be deallocated, because the Child is strongly referring to the parent. Swift/Objective-C won’t be able to take either of them out of the memory. Still confused? Let’s dive into the code then.

RetainCycle1

 

Above I have two classes RetainCycleObjCViewController and RetainCycleSwiftViewController (Left to Right).

I’ll try to explain the concept by creating Strong reference between the parent class and the block/closure in that class. Naming convention is same, for Swift, the name is aClosure and for Objective-C its aBlock.

@property (nonatomic) void (^aBlock)(void);

 

@property (nonatomic,strong) void (^aBlock)(void);

Any property written with (nonatomic) attribute type in Objective-C, is by default strong as well. Therefore both of the above statements are similar.

For Swift we don’t specify the strong attribute as well. By default the properties are strong.

Objective-C uses atomic and nonatomic for thread safe vs non thread safe operations, but swift has no where abouts of these. At-least I could not find any low level documentation for this (If you know, please leave a comment). But honestly, I have been on like 15+ projects and never in any of them I ever needed to create an atomic property.
Back to our example, here we see that both Swift and Objective-C controllers are strongly pointing to the aClosure() and aBlock() respectively. In the definition of both of these (uncommented definition, red boxes), we see that we are trying to access myString property of the class. In order to do that, we have to go through our class only, using the dot operator. This will create a retain cycle. Now, your class has a strong reference to the block/closure and block/closure has a strong reference to the class.

You would say, hey where did I ever write the code that block/closure is pointing to self/MyClass? The reason is, blocks/closures will use self as a strong reference. This is known as Capturing the variables.

The good old Objective-C is even giving us the warning. Its cut-off in the image, but here is the full warning: Capturing ‘self’ strongly in this block is likely to lead to a retain cycle.

Notice the backTap and deinit/dealloc methods? If you present both of these controllers from a different view controller, and then dismiss them via backTap, you would think that deinit/dealloc for both the controllers would be called right? Since you dismissed it, it should not be in the memory anymore. Hmm, but no, since while the deallocation of your controller, the block/closure was still pointing to it strongly, it won’t be deallocated and deinit/dealloc would never be called.

 

How to get out of this? Easy ! Just make sure that one of the references is weak. The thumb rule is, a child should never be pointing to its parent strongly. Similarly here, we need to break the strong reference from our block to the parent view controller.


Just use the code in the green box and then dismiss your controller, comment the one in red box, you’ll see the deinit/dealloc methods will be called and print statements would be executed.

 

_ _weak typeof(self) weakSelf = self;

This is how you create a weak reference to self is Objective-C

1. _ _weak is an attribute.
2. typeOf() is kind of a dynamic type specifier, whatever you type in those round brackets, its data type will be used.
3. weakSelf is just a random name.

So, we are creating a weak reference to self or Parent class. Just use weakSelf  in the block, and free yourself from the clutches of retain cycle (too dramatic?).

 

aClosure = { [weak self] in
//Body of closure
};


This is how you create a weak reference to self in Swift:
1. [weak self], this is known as capture list. You can capture any amount of variables with this as weak. [weak param1, weak param2, weak param3]
2. in keyword specifies the start of the closure’s body. Whatever is written on the left side of in keyword in square brackets, signifies a capture list.

Leave a Reply

Your email address will not be published. Required fields are marked *


six − = 4

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>