Functional and Structural things on IOS

How memory management is handled on iOS?

Swift uses Automatic Reference Counting (ARC) which is conceptually the same thing as in Objective-C. ARC keeps track of strong references to instances of classes and increases or decreases their reference count accordingly when you assign or unassign instances of classes (reference types) to constants, properties, and variables. ARC does not increase or decrease reference count of value types because, when assigned, they are copied. By default, if you don't specify otherwise all the references will be strong references.
One of the gotchas of ARC to be aware of is Strong Reference Cycles. Under ARC for a class instance to be fully deallocated it needs to be free of all the strong references to it. But there is a chance you could structure your code the way that two instances strongly reference each other and therefore never let each other's reference count drop down to zero. There are two ways of resolving this in Swift: weak references and unowned references. Both of them will assign an instance without keeping a strong reference to it. Use weak keyword for one and unowned keyword for another before a property or variable declaration. Weak reference is used when you know that reference is allowed to become nil and unowned reference is used when you are certain that that reference has a longer lifecycle and will never become nil. Since weak references can have a value or can have no value at all they must be defined as optional variables. And unowned reference has to be defined as non-optional since it is assumed to always have a value.
Another important gotcha is Strong Reference Cycle in Closures. When you use closures within a class instance they could potentially capture self in them and if self, in turn, retains that closure than you'd have a mutual strong reference cycle between closure and class instance. It often occurs when you use lazy loaded properties, for example. To avoid that you'd use the same keywords weak and unowned. When you define your closure you should attach to its definition a so called capture list. A capture list defines how the closure would handle references captured in it. By default, if you don't use a capture list everything will be strongly referenced. Capture lists are defined either on the same line where the closure open bracket is or on the next line after that. They defined with a pair of square braces and each element in it has weak or unowned keyword prefix and is separated by commas. The same thinking as with variable references applies to closure capture list - define a capture variable as a weak optional if it could become nil at some point and the closure won't be deallocated before then, and define captured reference as unowned if it will never become nil before the closure is deallocated.


What  is  let  and  var  in  Swift?


let keyword is used to declare a constant and var keyword is used to declare a variable. Variables created with both of them are either references/pointers or values. The difference between them is that when you create a constant with let you have to give it a value upon declaration and you can't reassign it. And when you declare a variable with var it can either be assigned right away or at a later time or not at all (i.e. be nil).
This is a fundamental Swift thing that you should be familiar with. Unlike with Objective-C where everything is dynamic and can be nil and nil in turn can receive messages without breaking everything in Swift you have to be very explicit about what you are declaring.
At the end of the day letvarnil, and Optionals help define how you handle state in your apps. Swift forces you to be more explicit about it.


What is AutoLayout? When and where would you use it?

AutoLayout is a technology that helps you define relationships between views, called constraints, in a declarative way letting the framework calculate precise frames and positions of UI elements instead. AutoLayout came as an evolution of previously used Frames and auto-resizing masks. Apple created it to support various screen resolutions and sizes of iOS devices.
In the nutshell using AutoLayout instead of setting view frames you'll create NSLayoutConstraint objects either in code or use nibs or storyboards. NSLayoutConstraints describe how views relate to each other so that at runtime UIKit can decide what CGRect frames specifically to set for each view. It will adjust to different screen sizes or orientation changes based on the "rules" you defined using constraints.
The main things you'll be using working with AutoLayout are: NSLayoutRelationconstant, and priority.
  • NSLayoutRelation defines the nature of a constraint between two UI items/views. It can be lessThanOrEqualequal, or greaterThanOrEqual.
  • constant defines constraint value. It usually defines things like the distance between two views, or width of an item, or margin, etc.
  • priority defines how high of a priority a given constraint should take. Constraints with higher priority number take precedence over other. Priority typically is used to resolve conflicting constraints. For example, when there could be an absence of content we may want to align elements differently, in that scenario we'd create several constraints with different priority.

What is Optional in Swift?


In Objective-C nil used to be a very handy "value" for variables. It typically meant an absence of value, simply "nothing". You could send a message to a nil and instead of your app blowing up with an exception it would simply ignore it and do nothing (or return nil). In Swift, though, with introduction of let and var it became apparent that not all of the constants and variables can be defined and set at the time of declaration. We needed to somehow declare that a variable is undetermined yet and potentially could have a value or could have no value at all. That's where Optional comes into play.
Optional is defined with ? appended at the end of the variable type you declare. You can set a value to that variable right away or at a later time or not even set it at all. When you use Optional variables you have to either explicitly unwrap them, using ! at the end of the variable, to get the value stored in it or you could do a so-called Optional Binding to find out whether an optional contains a value. To do that you'd use a
if let unwrappedOptional = someOptional {  
  // your code here 
}
construct.
Optionals cannot be used with constants (lets) because a constant has to be defined at the time of its declaration and therefore has value is not an Optional.
Unlike in Objective-C in Swift sending messages to nil causes a runtime exception. But there is a way to do something somewhat similar in Swift where you could send a message to an Optional but if optional is a nil than instead of raising an exception it will just ignore it and return nil, much like the old Objective-C behavior. That allows you to do method chaining calls and if one of the optional values in the call sequence is nil then the whole chain will return nil.
Optionals make Swift lean more towards the functional side of programming languages partially mimicking Maybe concept of Haskel and similar languages. At the end of the day just like letvar, and nil Optional is a helpful construct that forces you to be more mindful of you handle the state of your applications.
In general, you should be very mindful of the state of your applications and use nil and consequently Optionals to represent an absence of value as less as possible. Every time you declare an Optional ask yourself a few times if you really really need it.
NOTE: Objective-C now has nonull and nullable directives to give it more Swift-like  
explicit variable type declaration.  


Comments

Post a Comment

Popular posts from this blog

iOS Architecture

Performance Tips for IOS Application

setNeedsLayout vs layoutIfNeeded Explained