Sign In Start Free Trial
Account

Add to playlist

Create a Playlist

Modal Close icon
You need to login to use this feature.
  • Book Overview & Buying iOS Programming Cookbook
  • Table Of Contents Toc
iOS Programming Cookbook

iOS Programming Cookbook

By : Hossam Ghareeb
3.5 (2)
close
close
iOS Programming Cookbook

iOS Programming Cookbook

3.5 (2)
By: Hossam Ghareeb

Overview of this book

Do you want to understand all the facets of iOS programming and build complex iOS apps? Then you have come to the right place. This problem-solution guide will help you to eliminate expensive learning curves and focus on specific issues to make you proficient at tasks and the speed-up time involved. Beginning with some advanced UI components such as Stack Views and UICollectionView, you will gradually move on to building an interface efficiently. You will work through adding gesture recognizer and touch elements on table cells for custom actions. You will work with the Photos framework to access and manipulate photos. You will then prepare your app for multitasking and write responsive and highly efficient apps. Next, you will integrate maps and core location services while making your app more secure through various encryption methods. Finally, you will dive deep into the advanced techniques of implementing notifications while working with memory management and optimizing the performance of your apps. By the end of the book, you will master most of the latest iOS 10 frameworks.
Table of Contents (16 chapters)
close
close

Working with memory management and ARC

If you are coming from the old school where MRC (Manual Reference Counting) was being used for memory management, you definitely know how much headache developers suffer to manage memory in iOS. With iOS 5, Apple introduced ARC (Automatic Reference Counting), and life became easier in terms of memory management. Though ARC manages your memory automatically, some mistakes may ruin your memory with no mercy if you didn't understand the concept of memory management.

Getting ready

Before checking how to manage memory and avoid some common mistakes, I would like to highlight some notes:

  • Assigning a class instance to variable, constant, or properties will create a strong reference to this instance. The instance will be kept in memory as long as you use it.
  • Setting the reference to nil will reduce its reference counting by one (once it reaches zero, it will be deallocated from memory). When your class deallocated from memory, all class instance properties will be set to nil as well.

How to do it...

  1. Create two classes, Person and Dog, with a relation between them, as shown in the following code snippet (this code snippet has a memory issue called reference cycle):
      class Dog{
        var name: String
        var owner: Person!
        init(name: String){
          self.name = name
        }
      }
      class Person{
        var name: String
        var id: Int
        var dogs = [Dog]()
        init(name: String, id: Int){
          self.name = name
          self.id = id
        }
      }
      let john = Person(name: "John", id: 1)
      let rex = Dog(name: "Rex")
      let rocky = Dog(name: "Rocky")
      john.dogs += [rex, rocky] // append dogs
      rex.owner = john
      rocky.owner = john
  1. Update the reference type of owner property in the Dog class to break this cycle:
      class Dog{
        var name: String
        weak var owner: Person!
        init(name: String){
        self.name = name
      }
    }

How it works...

We have started our example by creating two classes, Person and Dog. The Person class has one-to-many relation to the Dog class via the property array dogs. The Dog class has one-to-one relation to class Person via the property owner. Everything looks good, and it works fine if you tested, but unfortunately we did a terrible mistake. We have a retain cycle problem here, which means we have two objects in memory; each one has a strong reference to the other. This leads to a cycle that prevents both of them from being deallocated from memory.

This problem is a common problem in iOS, and not all developers note it while coding. We call it as parent-child relation. Parent (in our case, it's the Person class) should always have a strong reference to child (the Dog class); child should always have a weak reference to the parent. Child doesn't need to have strong reference to parent, as child should never exit when parent is deallocated from memory.

To solve such a problem, you have to break the cycle by marking one of these references as weak. In step 2, we see how we solved the problem by marking the property owner as weak.

There's more...

The reference cycle problem can happen in situations other than relations between classes. When you use closure, there is a case where you may face a retain cycle. It happens when you assign a closure to a property in class instance and then this closure captures the instance. Let's consider the following example:

class HTMLElement { 
 
let name: String 
let text: String? 
 
lazy var asHTML: () -> String = { 
if let text = self.text { 
return "<\(self.name)>\(text)</\(self.name)>" 
        } else { 
return "<\(self.name) />" 
        } 
    } 
 
init(name: String, text: String? = nil) { 
        self.name = name 
self.text = text 
    } 
} 
 
let heading = HTMLElement(name: "h1", text: "h1 title") 
print(heading.asHTML()) // <h1>h1 title</h1> 

We have the HTMLElement class, which has closure property asHTML. Then, we created an instance of that class which is heading, and then we called the closure to return HTML text. The code works fine, but as we said, it has a reference cycle. The instance set closure to one of its property, and the closure captures the instance (happens when we call self.name and self.text inside the closure). The closure in that case will retain self (have a strong reference to the heading instance), and at the same time, heading already has a strong reference to its property asHTML. To solve reference cycle made with closure, add the following line of code as first line in closure:

[unownedself] in 

So, the class will look like this:

class HTMLElement { 
 
let name: String 
let text: String? 
 
lazy var asHTML: () -> String = { 
 
        [unownedself] in 
 
if let text = self.text { 
return "<\(self.name)>\(text)</\(self.name)>" 
        } else { 
return "<\(self.name) />" 
        } 
    } 
 
init(name: String, text: String? = nil) { 
        self.name = name 
self.text = text 
    } 
} 

The unowned keyword informs the closure to use a weak reference to self instead of the strong default reference. In that case, we break the cycle and everything goes fine.

CONTINUE READING
83
Tech Concepts
36
Programming languages
73
Tech Tools
Icon Unlimited access to the largest independent learning library in tech of over 8,000 expert-authored tech books and videos.
Icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Icon 50+ new titles added per month and exclusive early access to books as they are being written.
iOS Programming Cookbook
notes
bookmark Notes and Bookmarks search Search in title playlist Add to playlist download Download options font-size Font size

Change the font size

margin-width Margin width

Change margin width

day-mode Day/Sepia/Night Modes

Change background colour

Close icon Search
Country selected

Close icon Your notes and bookmarks

Confirmation

Modal Close icon
claim successful

Buy this book with your credits?

Modal Close icon
Are you sure you want to buy this book with one of your credits?
Close
YES, BUY

Submit Your Feedback

Modal Close icon
Modal Close icon
Modal Close icon