iOS Topics

Let | Var | Reference & Value Types

This is about as short a post as it can get! For a deeper look at reference & value types in Swift, see my other post on the topic.

I see a lot of questions on SO that discuss mutability in Swift. Let's go over some basic points about mutable (and immutable) objects in Swift:

  1. Creating a let variable enforces immutability - that variable cannot point to a different piece of data. You cannot change the data at that memory adddress and you also can't point the variable to a different memory address. Say you have let a = 5 and let b = 8.
    You cannot then say a = b nor can you say a = 7.
  2. If you have a var variable, all that means is that your variable can be reassigned - that could mean that the value it points to changes or that you point it to a different memory address.
  3. Structs, enums and other Swift value types (primitives such as Int, Double, String, Array, Dictionary and Set) dispay deep copy semantics. This means that if two variable are pointing to the same memory location, changing the data of one won't change the data of the other. A deep copy of the changed variable will be made and it'll point to its own separate memory address. Each value type instance holds a unique reference to its data. The ability of values to point to the same memory address until they no longer have the same data is due to Swift's Copy-On-Write optimization.
    //Assume Student() is a struct that initializes a student with an age.
    let a = Student(25)
    let b = a
    print(a.age) //25
    print(b.age) //25
    a.age = 35
    print(a.age) //35
    print(b.age) //25
    • As you can see above, changing a property value for a won't cause a change in b. Additionally, both will point to the same memory address until we change a.age - then a deep copy is made, passed to b, and the two variables point to different places in memory
  4. With reference types (often classes) multiple instances can share a single copy of data (they can point to the same memory address). If we pass a class instance to a function, for example, we're actually passing in a reference to the memory address of the object.
    //Assume Student() is a class that initializes a student with an age.
    let a = Student(25)
    let b = a
    print(a.age) //25
    print(b.age) //25
    a.age = 35
    print(a.age) //35
    print(b.age) //35
    • Since we're dealing with reference types, a shallow copy is made, meaning both instances are pointing to the same memory address. A change to data in one will result in change to data in the other.
    • With reference types, it's easy to leave around many reference to an object. Changing data of one reference will change the rest, and this can result in unexpected behavior and leads to bugs. Immutable types are considered safer and can lead to more bug-free code.

Architecture - View and Navigation Logic Abstraction

Views

Aside from pulling out protocol code and putting it into its own file (as covered in my most recent post), we can also pull out view code to reduce the size of our VCs. 

In a typical VC, say we are putting view setup code into our "viewDidLoad" method - we may instantiate several UI components and add them as subviews here. You may choose to create other methods that customize the subclassed UI components when called (which we do from viewDidLoad), ending the customization with adding the component as a subview. This may include using Visual Formatting Language to implement AutoLayout in code. See below:

class BloatedVC: UIViewController {

  private let restaurantName = UILabel()

  private let restaurantImage = UIImageView()

  private let blankSpaceSeparator = UIView()


  override func viewDidLoad() {

  super.viewDidLoad()

  view.addSubview(restaurantName)

  view.addSubview(restaurantImage)

  view.addSubview(blankSpaceSeparator)

  // add a ton of constraint code here, along with other customization including fram  e sizing, color, animations, etc.

  }
}

Here's a thought - instead of putting this code into a VC, why not factor it out into a subclass of UIView? We can have all the same code in that subclass, literally the exact same code, but instead of putting it all in our VC, we just create an instance of that new class in our VC and say

class BloatedVC: UIViewController {

  private var viewObject: ExtractedVCViewCode?

  override func loadView() {
  if let abstractedView = viewObject {
  self.view = abstractedView
    }
  }
}

It's important to note that we set up our view in "loadView", not "viewDidLoad". This is called by a VC when its view is currently nil, so you can instantiate the abstracted view in there.

The code for the abstracted view looks almost identical to the original code we had in "viewDidLoad":

class ExtractedVCViewCode: UIView {

  private let restaurantName = UILabel()
  private let restaurantImage = UIImageView()
  private let blankSpaceSeparator = UIView()

  struct LayoutConstants {
    static let padding: CGFloat = 15.0
    //other constants here for use in autolayout
  }

  override init(frame: CGRect) {
    super.init(frame:frame)
    addSubview(restaurantName)
    addSubview(restaurantImage)
    addSubview(blankSpaceSeparator)

    // add a ton of constraint code here, along with other customization including g     frame sizing, color, animations, etc.
  }

  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
  }
}

Navigation

Another quick (and to some, perhaps insignificant) way to reduce the amount of code in a VC is by separating out navigation logic - if a cell is clicked, instantiate this VC, pass in this restaurant as the data being provided, and present VC. This won't work for you if you're using IB segues (I prefer writing everything in code for many reasons unless I have a very simple idea I want to quickly prototype). 

First, we have two view controllers - the first displays a list of restaurants, the second displays information for one specific restaurant. We'll leave out typical navigation code, as it will be handled by a third class that neither VC knows about (yay for abstraction). Here's the gist of things - VC #1 declares a protocol with a method that takes a restaurant object as an argument - we also declare a weak var delegate that is of that delegate type. In "didSelectRowAtIndexPath", we invoke that method and say "whoever is implementing our delegate method, go ahead and execute now, here's the restaurant object you'll be needing". That's ALL THE CODE we have for navigation in our first VC.

The third class, that "navigation event handler", is what conforms to the protocol (the code below refers to this class as the "DefaultCoordinator"). This class is what will act as our delegate and actually execute our navigation code. VC #2 doesn't do anything in terms of navigation - it just exists here. The flow of things is VC #1 -> call method in navigation event handler and pass it restaurant object -> navigation event handler creates instance of VC #2, passes restaurant object over to it and pushes it onto the nav stack. Let's check out the code: 

class Restaurant: NSObject {
    var restoName: String
    var restoPic: UIImageView
    
    init (name: String, picture: UIImageView) {
        self.restoName = name
        self.restoPic = picture
        super.init()
    }
}

protocol RestaurantTableViewControllerDelegate:class {
    func RestoTableViewDidSelectRestaurant(restaurant: Restaurant)
}

class RestaurantListVC: UITableViewController {
    weak var navigationDelegate: RestaurantTableViewControllerDelegate?
    private var restaurants = [Restaurant] ()
    
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let selectedResto = restaurants[indexPath.row]
        navigationDelegate?.RestoTableViewDidSelectRestaurant(selectedResto)
    }
}

class DefaultCoordinator: RestaurantTableViewControllerDelegate {
    weak var navigationController: UINavigationController?
    
    func RestoTableViewDidSelectRestaurant(restaurant: Restaurant) {
        let VC = SingleRestaurantVC (restaurant: restaurant)
        navigationController?.pushViewController(VC, animated: true)
    }
}

class SingleRestaurantVC: UITableViewController {
    private var singleRestaurant: Restaurant?
    
    init (restaurant: Restaurant) {
        self.singleRestaurant = restaurant
        super.init(style: .Plain)
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

As you can see, the navigation code for the VC we are navigating away from is minimal. The DefaultCoordinator (which is acting as our navigation event handler) can conform to multiple protocols declared by multiple VCs - all navigation logic can be abstracted away and handled by the DefaultCoordinator. The (potential) downside is that once an app gets very complex with dozens of navigation options, it may be nicer to see the destination VC right there in the "from" VC (instead of tucked away in this coordinating class).

There are so many ways to reduce the amount of code in a VC - it's worth experimenting with. I find that it's easier for me to look at view controllers very conceptually instead of worrying about code involved - this lets me make up a sort of "map" in my head that allows for me to be more free-thinking in my architecture choices.

Architecture - MVC and MVVM

MVC - the typical architectural pattern for many web languages, Objective-C and Swift included. Separation of concerns exist nicely in this pattern - the most immediate problem we have is that Cocoa Touch has bundled our V and C together into a ViewController. Thus, we have view logic and "glue" logic all in one place. Any idea what this may lead to...? That's right! We end up creating a different type of MVC - a massive view controller!

Our views and controllers end up very tightly coupled, and a ton of logic is thrown into our VCs because we can't think of any other good place to put it. MVVM - Model, View, ViewModel, attempts to alleviate this by having a ViewModel act as the new "controller". This lets the ViewController class created by Apple to be JUST a view - no controller logic there. The controller is then truly factored out and acts as a link between the view (which is represented by a ViewController subclass) and our model. This architectural pattern relies on data binding between the view and the ViewModel - that is, when a change is triggered in the ViewModel (based on a change in the model), the changes should cascade down to the view through data binding - KVO, anyone?

This isn't really all that different from TRUE mvc - this is a problem, as far as I'm concerned. All we've done is create a new repository to dump things that we don't know where else to put - instead of putting this logic in a VC alongside view code, we lump it into the viewModel. Yeah, our ViewController classes have less code now and are more focused and testable, but instead of having bloated ViewControllers, we have bloated ViewModels. THIS IS NOT A COMPELLING REASON TO CHANGE ARCHITECTURE PATTERNS - the two good things I can say about MVVM are that 1. You own your ViewModel, whereas you were previously putting a lot of logic into a ViewController (which is created by Apple and not you) and 2. ViewControllers are more testable with this approach. 

What, then, can we do to truly improve our architecture? For one, create as many classes as you need to make sure that each file has single (or minimal) responsibility. Don't have a class called "BicycleVC" - instead, break that down into "BicyclePartsVC", "BicycleMaintenanceVC", etc. You don't even have to break it down into ViewControllers! Your files can just be regular objects that are used within another file, a controller somewhere else. By breaking down your files and naming them appropriately, all the while obsessively making sure that no class has too much responsibility, you greatly improve your architecture. No single class, not even a controller, will be saddled with too much responsibility and thus won't be saddled with too much code. 

ANY OTHER DEVELOPER SHOULD BE ABLE TO LOOK AT YOUR CLASS NAMES AND, WITHOUT LOOKING AT THE SOURCE CODE, DETERMINE WHAT EACH CLASS DOES AND HOW THE "PIECES FIT TOGETHER". 

Lots of data source code in a TableViewController subclass you're using? Factor it out. Lot's of networking code that encompasses multiple services being lobbed into your VC? Factor it out into several smaller classes, and, if it suits you, use a facade class to allow access to those (private, hopefully) internal APIs. When you think about it, a ViewModel is essentially a facade class used to access the model that is powering your software. Focus less on popular patterns and more on modularizing your classes, forcing minimal responsibility onto each class, and compulsively giving your files detailed names. 

The Xcode Build Process (& more)

The Build Process

Today I'm going to write about a few (read: many) things that I've been meaning to get to - I'll touch VERY briefly upon the Xcode build process, blocks & closures, symbolic links using terminal. A followup post will be about Unit Testing in Swift, and I'll possibly tack on an interesting (seemingly simple) coding problem at the end of the second post.

The build process! Xcode has hidden so many internals from us that without setting compiler flags and checking build logs, we really don't know exactly how our Swift or Objective-C code compiles to a machine code executable. Let's start with build logs, since they can be quite telling - the way to do this is to navigate to the "report navigator" tab in your file navigator (just hit Cmd+8). Build your project with cmd+B and then click "build" under project name dropdown. 

Results of displaying a build log in Xcode

Results of displaying a build log in Xcode

It's too much for me to go into what some of the dropdown information means (you can click on any of the build steps and a button to expand the process log should appear) - this is mostly because I just plain don't know. I did some googling around to try and find some reachable material for someone of my level, but it would take me longer than I want to spend on this article figuring out what it all means. With that being said, here are the basic steps of an Xcode build - preprocessing #include and import statements, compilation into assembly (you can view the assembly code by clicking "debug->debug workflow->always show disassembly),  machine code translation into an executable file and then linking executable files together (using the Mach-O linker). Magical, isn't it? There's more information about each step involved, but it does get very low-level; although it would take me a while to fully understand what happens under the hood of a build command, I know it's in my best interest to spend the time familiarizing myself with the process.

Delegates, Blocks & Closures

Imagine the following scenario - you have a tableview in which you need to download images on a background thread, display them if they exist, and if not, display some other placeholder image. You can't run this on the main thread since you'll be guaranteed to provide a horrible user experience - do it on a background thread. Delegation is a possible solution here since we have a one to one form of communication going on (controller to utility class doing the download). I personally think the best use case for delegation is passing data backwards to a parent controller - however, you can also use delegation to break controllers down into smaller modules and avoid large amounts of code in one place. Downloading images a nice example of that - we could also use GCD within the VC code to asynchronously download images. We could have something like:

    -(void) viewDidLoad {

    NSURL *urlForDownload = self.urlArray[objectAtIndexPath: indexPath.row];

    UIImage * cellImageToDisplay = [self downloadImageInBackgroundWithURL: urlForDownload];

    if (cellImageToDisplay) {

        cell.image = cellImageToDisplay;

    }}

    -(UIImage *)downloadImageInBackgroundWithURL:(NSURL *)url { ...a lot of code here...}

Assume that "downloadImageInBackgroundWithURL" returns a UIImage (we do all of the computation and type conversions within that method). This could add more code than we want to see in our ViewController, so we could break it up using delegates. Delegation requires three components: a protocol, a delegate and a delegator. The glue between the delegate and the delegator class is the protocol - both know about the protocol, but the delegator has no knowledge of the delegate. Makes sense, right? If you want something done, you don't care who does it, as long as they're capable of doing it. This is how delegation works - the delegating class has no knowledge of the class doing some kind of work - the way it knows that it is capable is because it implements the PROTOCOL methods.

Class A, a VC, adheres to a certain protocol. It says "ok, I promise to carry out these protocol methods". A model class (Class B), in this case an image downloading utility class, is aware of the protocol (I often declare them in the same class). It also has a weak property (to avoid retain cycles) called "delegate" which it knows will adhere to the protocol method(s). 

Class A imports the header from Class B, which gives it knowledge of the protocol methods and the "imageDownload" method implemented by Class B. It creates an instance of Class B and declares itself as ClassB.delegate, effectively saying that whenever Class B refers to a delegate within a method, that delegate will actually refer to Class A. We can call the "imageDownload" method from Class B and pass it a URL - Class B will then use that URL to download an image, and will call [self.delegate do something with the image we just downloaded]. Remember that self.delegate really means Class A, so now Class A has an image that has been downloaded for it in a totally separate class on a background thread. Delegation allows for some loose coupling, since Class B has no knowledge of Class A but still manages to send it data. If this sounds confusing, just check out the code screenshots below and it'll clear things up. This is a way to use delegates as a callback! 

Our protocol declaration (written in the same file as the delegating class).

Our protocol declaration (written in the same file as the delegating class).

The implementation of our delegating computation. This downloads an image based on what URL was passed to it and sends that data back to its delegate.

The implementation of our delegating computation. This downloads an image based on what URL was passed to it and sends that data back to its delegate.

This is the delegate class code. It implements the protocol method (which is called by Class B when it has finished downloading data). The protocol method is what gets passed the data as a parameter, which can then be used by the delegate (in this case, our ViewController class).

This is the delegate class code. It implements the protocol method (which is called by Class B when it has finished downloading data). The protocol method is what gets passed the data as a parameter, which can then be used by the delegate (in this case, our ViewController class).

This seems like a lot of code to download an image using an NSURLSessionTask - we could have put all of this code into our ViewController class, but that has 2 drawbacks: 1. It makes our controller file much larger and 2. It isn't reusable. By factoring out the image downloading code into a separate class and including a protocol, any other class can conform to this protocol and have images downloaded asynchronously without having to write more code.

Onto blocks and closures - anonymous functions that can be passed around as objects. Known in other languages as lambda functions, blocks have the useful ability to capture variables in the same lexical scope (lexical scope refers to a practice whereby a range of functionality of a variable is set so that it can only be accessed from the code in which it has been defined). Blocks are then, essentially, objects that can carry out some computation or perform some operation (think function or method) while being able to use variables defined outside of the block. can be used in place of delegation, since instead of dealing with a large amount of code that potentially isn't reusable, we can just create a block and define and use it inline. Think of blocks as some object you can use to carry data and throw around. Complete some task, call a block and pass it the data, throw it to a controller (which will call the method to complete said task and implement the block), and use the data that was passed. Ta-da! A perfect way to create cleanly-written callbacks. 

The same task can be accomplished (arguable more elegantly) using blocks! That's right, we've finally arrived at blocks...the syntax can be intimidating (which is often dealt with by using typedef to make them more readable), but worry not - click here for a quick guide to block syntax. Let's look at some code that makes use of blocks and also downloads images asynchronously - the key difference to note between this technique and the delegate approach is that with blocks, we don't need to declare a protocol and implement some separate method that makes use of the data. We can just call the block from wherever we want and use the code right there in the same lexical scope. No extra method, less code, and variables right in front of your face so there's no confusion about what data is being used and where it came from.

 *NOTE - You can refer to "self" within a block; this will result in a memory leak for the simple fact that blocks hold strong references to self parameters used within the block. The way around this is to use a "block variable" - this is declared before the block and simply REDECLARES self as a weak variable. You then use that block variable within the block body. 

If you wanted to use blocks to download images for a tableView, it's important to keep data synchronized so that the tableView cell receives and displays the correct image. You also need to think about caching images, checking for an existing image for that data model instance before downloading it (if it doesn't exist, download it and save it to that model instance. Other things that could be considered include 1. How to save downloaded images to disk as a file and store the file path to the model instance 2. The best way to load images from disk asynchronously 3. Figure out an efficient way to find out whether the image exists on disk so that you know whether to load it or download it 4. Choosing how you want to clear the cache 5. Factoring all of this logic out of a VC. It clearly isn't as simple as calling a download method with a completion handler at the end. 

Here we actually process the data, downloading an image based on a URL passed to the method.

Here we actually process the data, downloading an image based on a URL passed to the method.

We call the block from our VC and use the data contained in it.

We call the block from our VC and use the data contained in it.

As you can see, we require significantly less code when using a block based callback method. We use the build in NSURLSession API to create a task and download the image, and we call our completion handler (which we passed as an argument to our download method) on the main thread. 

The block we created as an argument for our method is able to hold a BOOL and a UIImage as parameters - the block itself doesn't do anything with this data other than carry it around. In our VC is where we invoke the block, gain access to the data it's carrying with it, and do something with that data. Concise, elegant, and you can see exactly what's going on inline!

 

Symlinks

Symbolic links, which we can create at the command line, allow an object to point to a different object in the file system. They're like aliases for whatever you're pointing to - instead of having to type in the file path for SublimeText in order to use it to open a particular file, you can create a symlink for it and have "sublime" point to that executable file path. 

The way to create a symlink is to use the terminal command "ln -s", followed by the original file path, followed by the alias file path. If you had an installed version of SublimeText sitting in your "Downloads" folder, here's how you would set up a symlink so that typing "sublime" at any point in a terminal session (outside of running a server or being in REPL) will open SublimeText:

    $ ln -s~/Downloads/Sublime\ Text\2.app/Contents/SharedSupport/bin/subl /usr/local/bin/sublime

The ln -s command tells the system we're creating a symbolic link. Sublime Text 2 actually has a unix executable file that is hidden in the package contents. We want to point to that by creating an alias (a symlink) in our local user bin directory. The bolded part is where we are doing that - adding "sublime" at the end tells the system that when we type "sublime" in to terminal, we want to access the unix executable file path that comes bundled with Sublime Text 2. 

 

 

 

 

 

Reference and Value Types in Swift

References and Values in Theory

In Swift, a class is considered a reference type, plain and simple. This is similar to Objective-C, where everything that inherits from NSObject is a reference type. Being a reference type means that references share one single copy of data in memory, and they all refer to that same memory address. An issue with this involves the mutability of such an object - if somebody using a reference to Object A in a class changes some mutable values around, and I’m using Object A in a different class and I’m expecting a different value, we have a problem. 

Structs, enums and tuples are all value types in Swift (Objective-C also uses value types in number literals or C structs). If we say that:

let entree = Entree ()

let entree.protein = “Tofu”

let meal = entree

meal.protein = “Chicken”

Then entree.protein should ALSO have a value of “Chicken”. Both entree and meal reference the same object in memory, so changing the value of one changes the other. 

If we redefined the above as a struct, then the it would become a value type, and changing one would NOT change the other. Changing the protein value of meal wouldn’t change the protein value of entree.

It’s important to note that “let” as a constant keyword means different things for value and reference types - for reference types, let means that the reference must remain constant, but the properties are mutable. For value types, let means that the instance must remain constant, meaning that properties are immutable. 

Struct foo { var isReferenceType = False }

Class foo2 {var isReferenceType = True }

let exampleOne = foo ()

let exampleTwo = foo2 ()

// the below code WON’T work, since we are attempting to change the reference of a reference type

exampleTwo = foo

//the below code WILL work, since we are attempting to change a property value for a reference type

exampleTwo.isReferenceType = False

//the below code WON’T work, since we are attempting to change a property value for a value type

exampleOne.isReferenceType = True

 

To sum up, we can’t change the reference of a let constant if it’s a class, but we can change property values of that reference. We also can’t change property values of a let constant if it’s a struct. 


It’s important to note that Swift favors values almost exclusively. If you need to compare two struct instances for equality (assume we’re talking about value equality, not memory equality) then we need to conform to the Equatable protocol (this is something often required with value types). 

extension structName: Equatable { 

    func == (firstArgument: structName, secondArgument: structName) {

        return (firstArgument.value1 == secondArgument.value1) && (firstArgument.value2 == secondArgument.value2)

    }

}

To make data thread-safe, we would need to use a reference type (class) and implement locking. If you need to compare memory (physical) equality, then you should use a reference type. 

References and Values in Practice

Swift makes use of an optimization technique known as Copy-on-Write for value types - if you assign Object B = Object A, Swift will let both share a memory address even though they're value types. Object B will simply contain a reference to Object A. When the value of one changes, a copy is made, and the objects no longer share a memory address. In a cool optimization twist, if you later change one other object to match the other AGAIN, they'll once again share a memory address.

With some low-level Swift programming (of which there are a few resources about online, none of them actually any good), you can prove that copy-on-write exists - HOWEVER, it only seems to work for a few built-in types (such as arrays)! That's because if you want all that optimized goodness that comes from copy-on-write, you've got to implement it yourself for your custom value types. 

To learn about implementing it yourself, and how to build a Swift array from scratch, check out this article by Mike Ash. He runs an incredibly deep and advanced blog on Objective-C and Swift programming, and writes articles all the way down to the compiler level. Most of it is beyond me right now, but it's still good to glance at. 

You mix and match reference and value types all the time - remember that literals are value types, so whenever you have a a class variable that’s a string or a custom struct you created in a different file, your class is a reference type containing value types. This is common, and works out nicely. 

Things get tricky when you have a reference type contained within a value type. 

Let’s get something cleared up that’s related to the protocol-oriented nature of swift - value types should be equatable! This the expected behavior of a value type (as mentioned in a WWDC15 talk); if we have two integers (a value type in swift), don’t we expect to be able to compare their VALUES? I know I do. The same goes for strings, which, as a literal, are also equatable value types. 

Value types need to implement the == operator. The three properties of equality that must be addressed are that the comparison must be reflexive, symmetric and transitive

  1. To be reflexive, we must make sure that “x == x” returns true.
  2. To be symmetric, we must make sure that “x==y” and “y==x” return the same value, whether true or false.
  3. To be transitive, our == operator must make sure that is “a==b” is true, and “b==c” is true, then “a==c” must also be true. 

If your struct contains variables that are already literal value types, then you can declare the equatable function as a global function and simply compare the variables using the == operator. If your struct contains a struct, that nested struct should also conform to the equatable protocol in order to work your way up. It’s also convention to declare protocol adherence as an extension of the Type definition. 

Making reference types equatable is slightly different - it’s entirely case-specific. Say you have a “Person” class (a reference type) - it has a name variable. Two people can have the same name, but be different people. So how you implement whether or not they're equatable is up to you. 

Let’s return to a value type containing a reference type. We can have a struct be mutated very easily if it contains a reference type. There are ways around this, some better than others, which we’ll visit in a moment. Look at the screenshot below - we have two struct instances, one equal to the other (remember copy-on-write here). We change the value of a reference type variables of the first - desired behavior would be that since they’re both value types, changing data in one wouldn’t affect the other. Not so.

We've managed to mutate a struct by changing data in a different struct! This showcases their coupling based on the existence of a reference type in the struct definition.

We've managed to mutate a struct by changing data in a different struct! This showcases their coupling based on the existence of a reference type in the struct definition.

We can prevent this by forcing our Restaurant to use an explicit initializer - this actually creates a copy of the Person being passed in, instead of holding a reference to it. If we do this, and we pass in "managerTest" to be the manager, our Restaurant will use a COPY of the "managerTest" object. You can check the memory addresses and see that they're different. This means that mutating values of the "managerTest" object won't mutate the "manager" property of our Restaurant. Without this initializer, the two share a memory address, so mutating one mutates the other. The flaw in our design is when we act directly on "bestResto.manager.name" - there is nothing preventing this kind of mutation. 

We can mutate struct values here by just acting directly on the struct instance instead of the original reference type we used to create the "Manager".

We can mutate struct values here by just acting directly on the struct instance instead of the original reference type we used to create the "Manager".

The concept at hand here, a far cry from where we came, is data encapsulation. We've covered this in a previous post, but not with the complexity of a reference type contained within a value type. Let's start planning: a good solution would be to create setters and getters for the “manager” property of our Restaurant struct - get simply returns the current value, and set would create a copy of the manager and set the “manager” property to be equal to the new value. This way, if the data is changed, a deep copy of the reference type is created (vs a shallow copy, which creates a new object that simply points to the copied object...aka a referencing object). 

See any problems with this? I do. For one, we're creating a copy every single time the data is written to, instead of just mutating the existing copy. How can we say "If this object is currently referencing another object (shared resource) then make a deep copy with the changes. If nothing else is referencing this, just mutate the existing object instead of making a copy"? In comes "isUniquelyReferencedNonObjC", a method that detects the reference count of an object and returns a boolean value. You pass in the address of an object, it find other references to that object, and if there are no other references, it returns "True". Basically, if this returns "True" for our manager object, it has nothing else referencing it, and we can just mutate the existing copy. This raises a few questions that we'll address in a moment. 

Check out the code below - this is in a project. We have out VC code which creates two structs, the second equal to the first. We check the memory address of the MANAGER (which is a reference type), NOT the struct. We only implemented copy-on-write for the manager here - remember that custom structs don't implement copy-on-write automatically, so if we wanted that, we'd have to implement it ourselves. In this case, we just did it for the Person object. 

The managers share the same memory address - this is what we'd expect. After we change the manager object of the second restaurant object, the memory addresses are suddenly different! Our copy-on-write worked! The "withUnsafePointer" code is how we get the memory address of a struct. This is to prove that our struct doesn't implement copy-on-write (they have different addresses in memory from the very beginning, even though they have equivalent values). The other functions used to obtain memory addresses are just C functions that we're using in our Swift code.  

Memory address console prints to show copy-on-write in action

Memory address console prints to show copy-on-write in action

The last thing I'll add is a screenshot of my code for Restaurant - it changed since the last time we wrote it. The "manager" variable is now private, and we can only change it by using explicit APIs - this is to avoid developers accidentally changing the manager of a restaurant. If they want to change it, they call a clearly defined API that tells them exactly what they're doing so that any confusion is avoided. We get the current manager through a computed property "currentManager" and we implement copy-on-write in our "assignNewManager" function. The function is mutating since, if the manager object is uniquely referenced, we want to change it in place. Else, create a copy of the manager being passed in and assign it to our manager property. 

Encapsulated logic for creating a Restaurant struct

Encapsulated logic for creating a Restaurant struct

There's one more thing to talk about! What if we want to have two restaurants that share the same manager? This is a perfect representation of our situation - Restaurants are unique, and so should be value types. Managers can be the same person, and so CAN be references, but managers with the same name can ALSO be unique, and so CAN be value types (read - structs). Solution - it doesn't work here. We can create a new Restaurant object and pass in the Person we created as the manager, but our init method forces a copy to be made. We need to tinker with our init method and perhaps implement copy-on-write somewhere else in our code.

There are other edge cases to consider where our code WILL NOT WORK. I've been racking my brains for a few days here and there, trying to come up with an elegant solution that works. I'll keep working on it and I'll be sure to post here when I find a good solution.

That’s a ton to cover - we’ve reviewed lazy variables and working with constants, lazy sequences, reference and value types, equatable protocol implementation for value types, and discussed scenarios where you may WANT to have a reference type within a value type and how to write solid, defensive code in that situation. This was a long post, but definitely one of value. 

Being Lazy in Swift

Lazy Variables & Constants in Swift

Say you’re working on some application that has optional features - perhaps you have an image that CAN be resized if a thumbnail is required, but there is a chance that a thumbnail will never be viewed. Image scaling algorithms are computationally taxing - what if our user never ends up accessing a thumbnail? In that case, it doesn’t seem right to demand that a user ALWAYS wait for such an operation to be performed. Remember, allocation is slow, so defer until needed, and memory is limited, so don’t waste it. Use lazy instantiating when the initial value for a property isn’t known until after object initialization, when performing some intense algorithm or perhaps when calculating a large number (like pi to a large number of digits). 

In comes lazy loading - this is a technique used to defer instantiation of a variable or sequence (in swift) until it is actively needed. In swift, if you have a variable in a class that is part of the class’ designated initializer, the value must be computed since the compiler forces that every property within an initializer method be initialized. That may look something like this:

extension UIImage {

    fun resizedTo(size: CGSize) -> UIImage {

        // insert algorithm here    

    }

}

Class UserImage {

    static let smallSize = CGSize(width:36, height: 36)

    var thumbnail: UIImage

    var defaultImage: UIImage

    init (defaultImage: UIImage) {
        self.defaultImage = defaultImage

        self.thumbnail = defaultImage.resizedTo(UserImage.smallSize)

    }

}

What if we never need to use the thumbnail? We just performed an intensive operation for no reason at all - lazy variables take away this problem. In Objc we could leave the thumbnail out of the initializer and do a check for its value by making the thumbnail a computed property with set and get values. In the get, if the value is nil, THEN we would call our resizedTo method; in the set, simply give it a new value. We can immediately set a thumbnail value if we wish to, but if we end up attempting to access it without having initially set a value, it will call our resizing method. Thankfully, lazy instantiation with swift allows us to write less code while still achieving the same result.

The above can be achieved with just a single line of code- 

lazy var thumbnail: UIImage = self.defaultImage.resizedTo(UserImage.smallSize)

If we need to add more lines of code to compute our property, we can just use a closure - 

lazy var thumbnail: UIImage = { 

    let size = CGSize(

        width:min(UserImage.smallSize.width, self.defaultImage.size.width), 

        height: min(UserImage.smallSize.height, self.defaultImage.size.height)

    return self.defaultImage.resizedTo(size) 

} ()

The fact that a property is lazy means the value will only be computed when the entire class has been initialized, so it is safe to reference self within a computed lazy property. 

Note that let constants, if declared at global scope or as a type property (static let) are automatically lazy. Other than that, you can’t make them lazy. An interesting thing to note, as stated by Chris Lattner (designer and project leader of LLVM, Clang and Swift), is that “let” is about physical immutability, not logical immutability. Physical immutability means that once the bits are set in memory (when the let value is initialized), they can’t be changed.

Lazy Sequences in Swift

The SequenceType and CollectionType protocols in Swift have a computed property named lazy - it returns a LazySequence or LazyCollection, depending on which protocol we’re implementing. Lazy applies only to high-order functions in Swift (array.lazy.map(addOneFunction)). This code would only execute for values we actually need; if we printed (array[0], array[10], array[20]) and lazily mapped our function to those values, our program would only make three calculations, one for each value we try to access. If our array has 20,000 elements in it, we can use this to avoid calculating the values of each element after mapping a function to it, and limit our processing to just the values we want. 

Swift Generics

Generic programming refers to the ability to write functions and data types that don’t specify a type. In this way, an algorithm or, say, a collection data type can have high reusability and specify a type when instantiated. For example, an array can hold many kinds of objects - it’s a generic data structure. When you want an array that specially holds objects of type Struct Gen, you can declare it (specifically in swift) as:

var genericArray = [Gen]()

You could also declare an empty array of integers as:

var intArray = [Int]() or, using explicit generic syntax, as var intArray = Array<Int>()

In this way, it’s clear that there is one array type, but we can specify what types the array can hold. You can almost treat a data type as a function, with a type being passed as an argument.

Arrays, Dictionaries, and Optionals are all generic types in swift and, as such, they can only hold one type - they are type-safe data structures. There are workarounds for this - say you want an array that holds both instances of Struct A and Struct B. You can declare the generic array to hold type <Any>, which will allow you to insert objects of different types in the same array. 

*Note : when using <Any>, be aware that the compiler won’t check whether a method exists or not when called on an object of type Any. All returns of an <Any> instance would be an optional value - a safe way to access an object of type Any would be to type cast it. 

You can also have different classes conform to the same protocol and declare a generic array that takes <protocol> objects. However, this can get tricky - imagine you have two separate structs and both conform to the same protocol. Struct A has a function named “testing” that takes an int and returns an int, while Struct B has a function of the same name that takes a string and returns a string. Say you randomly grab an object from your array, call the “testing” function on that object, and pass it an integer. If you grabbed an object typed as class B, you’d have a problem.

If you wanted to write a function that took a generic collection and returned the first element, regardless of the type, you could write something like this:

func firstFromCollection<T: CollectionType>(a:T) ->(T.Generator.Element)?{

    guard !a.isEmpty else {

        return nil

    }

       return a.first 

}

We can call it for arrays and strings like so:

 

print(firstFromCollection([1,2,3,4]))

print(firstFromCollection(“abc".characters))

 

Swift is a protocol-oriented language, and GeneratorType is a protocol used with collections; it is used for iterating over collection types. Typical "for in" loops actually use generators under the hood in swift. Take this time to read more about generators, lazy mapping functions, guards and collection types. 

Check out my github for swift code (heavily commented, of course) to implement a generic linked list. When you create an instance of the data structure, you specify the element type! Generic programming FTW! Link to code here

Pay attention to one particular function in the generic linked list:

func replaceItemAtIndex (position: Int, withValue value : T).

Notice the second argument has "withValue value:T" - the "withValue" is referred to as an external parameter name. This means that a user of the function will see "withValue" as an argument being passed, which is slightly more explicit and readable than just "value". Internally, we use "value" to define our function. Think about which you'd prefer to see - 

replaceItemAtIndex(position:Int, value:T) or replaceItemAtIndex(position:Int, withValue:T)

The latter simply reads more like English; this is just a personal preference, but coming from Objective-C, I'm a fan of this. 

NOTE - The code for my linked list includes a CustomStringProtocol extension which allows for me to print the contents of my list by using the "print" function as in print(linkedList). Before doing this, I had to write a custom print function. Additionally, I've made use of subscripts (including setters and getters). This allows for array and dictionary like access to elements, either to get the element or set it - this looks like linkedList[0] to get the head node or linkedList[0] = "New" to replace the head node. Internally, the subscript just calls my getItemAtIndex function and my replaceItemAtIndex function. This exercise was extremely helpful in my getting used to general swiftyness, utilizing some of the important changes to the language when moving over from Objective-C. 

Writing pure swift code allows me to focus on new syntax and architecture rather than the Cocoa Touch API's. Learning how to use a framework doesn't mean you know best practices of the language itself - it's important to develop good habits early.

 

EXTERNAL RESOURCE:

This link is for a group of slides from a meetup presentation at Google HQ I went to on advanced generics! 

When To Use a Category

During a phone interview I had with Web M.D. recently (it started as a lightly technical interview and then I was thrown a curve ball - see the bottom for more) I was asked to define a category and explain when I'd use one. I gave an answer, but more importantly, I gave my answer. The interviewer responded with his own answer, and from the way he explained it, that was the answer he was looking for.

In reflecting back on that interview question, I would disagree with that my interviewer said about categories. He told me that "they should primarily be used when you don't have access to the source code of a class". While I agree that categories provide a useful way to extend functionality of classes that we don't have the source code for, there is no single right answer to this question. Categories can be useful in other ways, and can be less useful in just as many ways. In disagreeing with my interviewer (which I didn't express during the interview, although thinking back on it, I definitely should have), I'll list some of my ideas here:

  1. If you need to add functionality to a class but don't have access to the source code, use a category.
  2. If you need to add data to an existing class (properties or ivars), don't use categories, and instead just subclass and make use of inheritance. I say this because categories don't support adding properties or ivars (unless making use of associated objects, which I won't get into here). 
  3. If you have a totally oversized, bloated implementation file, consider breaking up the class into specific units by using categories
  4. If you want to provide some pseudo level of encapsulation, you can add "private" methods to a category and only selectively import that category filename. However, this isn't the only way to mimic encapsulation (you can use extensions, for example), so take this one with a pinch of salt.
  5. If you have instance of a specific class littered throughout your source code and suddenly need to add functionality to that class, use a category. Your alternative would be to create a subclass, add new methods, and then replace all of your instance with the new subclass. Inefficient, to say the least. This works to your benefit in (sort-of) reverse - if you have instances of a subclass somewhere, adding methods to the parent class through a category trickles down to the subclasses.  
  6. If you absolutely, 100% do not need to create a parent-child object hierarchy, use a category

The interview question I got that really shut me down was about graphing a curve using data points representing pollen levels. The interviewer was explaining to me that there are certain things a seasoned developer with a computer science degree would know how to do that I wouldn't (I have a degree in Environmental Science, which involved high level math and science coursework). To be totally honest, I think that even if I had majored in CS, I wouldn't have remembered anything about plotting points using bezier curves and the De Casteljau algorithm. Unfortunately, I was relayed the information that although I seemed to be a solid candidate, I wasn't technically experienced enough to join the team and hit the ground running. On to the next.

INSTANCE VARIABLES & PROPERTIES

INSTANCE VARIABLES VS PROPERTIES

An instance variable is a variable that exists and holds its value for the life of the object. Instance variables (or ivars, as they're commonly referred to) are available to the entire class that they're declared in - this is in contrast to local variables, which are available only to the method they are declared in. Generally, it is bad practice to directly set the value of an ivar - instead, we abstract this process by using setter and getter methods. The concept of instance variables (and properties) has a lot to do with data encapsulation, which we'll cover towards the end of this post.

Properties are simply variables that are backed by their ivars - by declaring a property, we create an instance variable and automatically generate setter and getter methods. Additionally, properties come with a list of attributes that we can use to help further shape and define our variables - readonly, readwrite, atomic, nonatomic, strong and copy.

A readonly property is when the backing ivars setter method is never synthesized.

A readwrite property generates both getters and setters.

An atomic property guarantees that a fully initialized object is always returned - the object is locked when being set or get so that it is not being simultaneously accessed from another thread. You will never see a "partial write" for an atomic property. Atomicity doesn't imply thread-safety! Consider an example where you have a first and last name, both atomic, both being accessed and set from two threads (one thread sets the initial first and last names, the other changes them). While you can always guarantee that you will be returned a full string for the first name and a full string for the last name (no partial writes), you cannot guarantee which thread is returning the value. You may get the original first name (from the first thread) and the changed last name (from the second thread), which is not the combination of values you perhaps expected.

A nonatomic property makes no guarantees regarding object initialization.

A strong property creates an owning relationship between the property and the assigned value. This is the default for properties. If a Car object has a @property (strong) Person *driver, and in our implementation file we write Car * Honda = [Car new]; and we have Person *John = [Person new]; and Honda.driver = John, then Honda has strong ownership of John. As long as Honda needs its driver, John will exist. 

A weak property creates a non-owning relationship between the property and the assigned value. This can be used to prevent retain cycles. In our previous example, if Person has a property called @property (strong) Car *car, and we have John and say John.car = Honda, we have a problem. Honda has strong ownership of its driver, John, but John also has strong ownership of his car, Honda. These objects, because of the strong relationship, will ALWAYS be owned by another object. If they’re no longer needed, they still can’t be destroyed - this is a retain cycle. A retain cycle is when two objects have a strong relationship to one another and thus can’t be destroyed, and no other objects hold a reference to either of them. The way around this is to use the weak property attribute - if John has weak ownership of his Honda, then we can avoid this retain cycle. If Honda is deallocated, because John has a weak relationship to it, that won’t be a problem - however, John.car will, by default, be set to nil. 

Keep in mind that if we want to use Key Value Observing (KVO), we must user properties in our classes. This is a means of notifying a current class when a property value has been accessed in a different class. It provides a means of communicating between different classes. Additionally, properties don’t HAVE to be global - if we declare them as class extensions (declared in our implementation file) as (readwrite), we can use them as we like in the class file. In the interface file, we can declare those same properties as (readonly) - other classes will not be able to write values to that property, essentially encapsulating that data. 

Data encapsulation encompasses the idea that data should be hidden and confined to a single area of software as much as possible, unless it is necessary that it be available to other classes. There are many, many ways to go about doing this, and it's up to the developer to decide how they want to go about it. You can hide ivars and properties in a class extension, making them available only to that class. You can create a category, use public variables, and import that category into your class for use. 

*As a side note, I almost always use properties instead of explicitly declaring ivars.

If data needs to be publicly available, it is bad practice to make it possible for other classes to change that variables value - in this case, you can declare a readonly property in a class interface file, and redeclare it as readwrite in the implementation file. This makes it so that you can internally change the value of that variable, but no other classes can write new values to it. To make properties "private" (although there is no such thing as a truly private variable in objective-c due to its dynamic runtime) you can simply put them in a class extension - this is my typical encapsulation workflow. dditionally, if you will be using publicly available variables from one class, but you are only using them internally, you can write your import statement for that class ONLY in your implementation file.

Between the @interface and @end tags, we have declared a private property. This is one way of using an extension to house private variables.&nbsp;  After the @implementation tag, we have declared both a private and public ivar between the curly braces. We can still achieve data encapsulation without using extensions, as shown here.&nbsp;

Between the @interface and @end tags, we have declared a private property. This is one way of using an extension to house private variables. 

After the @implementation tag, we have declared both a private and public ivar between the curly braces. We can still achieve data encapsulation without using extensions, as shown here. 

To recap - 

  1. Try and declare ivars or properties in categories as much as possible - this limits their exposure to the class they are declared in.
  2. If you need to expose a variable to other classes, try and make them readonly properties in your interface file and make them readwrite in your implementation file.
  3. All property variable are backed by ivars - they simply generate setters and getters automatically and come with several attributes you can utilize that deal with atomicity, encapsulation (readonly) and memory management.
  4. NOTE - If you don't want to put your variables in an extension, you can just put them in curly braces right after your @implementation "class name" in your .m file. This also encapsulates your data - I prefer using extensions because I think it makes my code more readable. 

Last but not least, if you want other classes to be able to change the values of a variable you have, you can keep the variable private and still accomplish this - create a public method, declared in your interface file, that internally changes the value of the private variable (see below). This is often used for further encapsulation, as it is bad practice in a large code base to allow other classes to directly change the value of an object. Once again, the way you choose to encapsulate your data depends entirely on your preferences and the data you have at hand - different pieces of software will always have different encapsulation requirements. 

On the left, we have the interface (.h) class file, and in it, we have a public readonly property and a public method. On the right, we have the implementation (.m) file with an extension declared. In the extension, we have redeclared our readonly property to be readwrite - other classes can now READ the variable value directly (it is publicly declared on the left) but cannot directly alter the value of it (since it's publicly readonly). In order to change the value, other classes must go through our publicly declared method, the implementation of which changes the property value.

On the left, we have the interface (.h) class file, and in it, we have a public readonly property and a public method. On the right, we have the implementation (.m) file with an extension declared. In the extension, we have redeclared our readonly property to be readwrite - other classes can now READ the variable value directly (it is publicly declared on the left) but cannot directly alter the value of it (since it's publicly readonly). In order to change the value, other classes must go through our publicly declared method, the implementation of which changes the property value.

NSUserDefaults, NSKeyedArchiver & NSCoding (Updated)

(Update) Apple documentation can be confusing - the serialization and archiver programming guide is one such example. There seem to be contradictory statements throughout; the guide doesn't really explain the way archivers, serializers, defaults databases and encoders work with each other. A little bit of further digging on the developer website helped me find a few scattered articles about these terms that were written more recently than the programming guide - I used this information collectively to help elucidate how these APIs and storage methods are related to each other. 

 

NSKeyedArchiver/NSCoder

Objects in memory can’t be passed around to other programs - they contain things like pointers that are only valid in the context of your current virtual memory space (which exists for each process in a multi-tasking OS). Serialization is the process of converting the in-memory representation of an object into a stream of bytes than can be passed between programs. In Cocoa and Cocoa Touch, NSKeyedArchiver is an API that we can use to serialize an object graph. 

If we want an object to be archivable, it must adhere to the NSCoder protocol methods, which encode and decode the objects. encodeWithEncoder and initWithEncoder are the two required protocol methods - the former tells the archiver how to serialize an object into bytes, and the latter tells the archiver how to transform the serialized data in an object. The NSCoding protocol methods go over objects one-by-one and encode both instance value and class type of the current object - the encoded objects are then archived.

You can then write your archive to data (turn the stream into NSData or write directly to a file path (if no path is specified, it goes to the root directory of the application). You can even archive to data and then write to NSUserDefaults (or archive to data and THEN write to a disk). It all just depends on your needs as a developer.

To archive to a data object, use the following code snippet as a guideline:

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self.array];

We can then either write to NSUserDefaults or directly to disk - to specify a file path where we want to store our archive, we can do something like this:

NSString *filename  = [NSHomeDirectory() stringByAppendingString:@"/Documents/app.bin"];

[data writeToFile:filename atomically:YES];

If an object graph doesn’t need to be serialized, and instead, an object hierarchy needs to be stored, we can skip archiving and go directly to NSUserDefaults (assuming we aren’t talking about custom objects). 

 

NSUserDefaults

NSUserDefaults provides a way to store small amounts of information, largely user preferences, in a “defaults database”. These parameters are called defaults because they’re commonly used to determine an application's default state at startup. At runtime, unboxing this defaults database can be accomplished with NSUserDefaults; in order to avoid constantly reading from that database throughout the lifecycle of an application, values can be cached. A method called synchronize is automatically called every so often, keeps the cached data synced with the defaults database.

NSUserDefaults can be used to store NSData, NSStrings, NSNumbers, NSDates, NSArrays or NSDictionaries. The call to NSUserDefaults is a thread-safe singleton that we use to set up a defaults database. We can also include a check when the app is running to see whether we have a database currently being used - if we do, use it, if not, create an instance using the singleton. 

In saving to our sharedInstance (the singleton) of NSUserDefaults, we can use the setObject: forKey: method, which takes any of the NSUserDefaults compatible objects and stores it with a key for quick lookup. We then synchronize to make sure that our cache is up to date. When retrieving, we call our sharedInstance and grab objectForKey:@“” and pass the key we know is associated with the object. 

*NOTE: If we want to store custom objects in NSUserDefaults (we may have such a small amount of data to persist that this makes sense), then we must implement NSCoder protocol methods and archive the objects. 

 

Conclusion

Trying to store custom objects? 

Implement NSCoding protocol methods to create a byte stream and use NSKeyedArchiver to create an archive of the data. If custom objects aren’t part of the equation, you can just go straight to NSUserDefaults.

 

So you’ve created an archive of encoded custom objects…where and how can you store them?

You can write your archive to an NSData object, and then either write that to disk or store it in NSUserDefaults. Alternatively, you can just write your archive directly to disk, either by specifying a file path or using the default one (the root directory of the application). 

Categories & Extensions

Categories provide a useful way to split a single class into multiple files. If we have, let’s say, a House class, it may have some methods like “buildWithMaterials” and “returnAddress” which returns the home address.

There may be methods that involve home maintenance such as “needsPlumbingRepair” or “paintWalls”. Instead of throwing these in the general class definition of House, we can include them in a category called “House+Maintenance”. This is a separate file that imports the House class header. At runtime, the methods included in this category will become part of the House class.

Say we create a subclass of House, and that subclassed object will ultimately require maintenance; we can then import the header file of our category so that we have access to the API. This declutters the original House class interface and implementation files, and reduces the number of methods in one place.

Another way we can utilize categories is to use them to hide certain methods. While we can’t truly make a method protected (due to Objective-C’s dynamic runtime), we can simulate one using a category. If we use our House example, let’s say we want a protected method called “marketValue” - we can create a new category for House called House+Protected. In the interface file, we list our marketValue method so that it is publicly available to classes that import this category. In our implementation file, we write the code for our marketValue method, returning some NSNumber.

In some other class where we may create an instance of House, we would be able to send messages to that House object and call a method that is included in the House class interface file. Remember, we should NOT have to import the House+Protected interface file to access those methods; that is the whole point of protecting those methods. If we don’t import the file, we can’t call the marketValue method that we want to; if we try to send the marketValue message to our House object, the compiler will complain.

In order to access the marketValue method, we need to include access to it in a subclass of House. If we create a subclass of House and call it Condo, we inherit all of the properties and methods that House contains, and we can add additional methods here. To hide our marketValue method, we only import House+Protected.h into the implementation file - here we can create a method (lets call it assessValue) and in defining assessValue, we can call our protected method (marketValue). We include assessValue in our Condo interface file, so that it is publicly available - behind the scenes, that method is calling our protected method.

If we import Condo into our main.m file, for example, and try to call out protected method on an instance of Condo *london = [[Condo alloc] init] by declaring [london marketValue], we will get a compiler error. Instead, we should call the Condo method that itself calls our protected method by writing [london assessValue].

One way to completely bypass all of this work is to simply use the performSelector method - since all methods are actually public in Objective-C, there are only ways to simulate privatizing them, although you cannot make them truly protected.

We could just say:
SEL protectedMethod = @selector(marketValue);
if ([london respondsToSelector:protectedMethod]) {
    [london performSelector:protectedMethod];
}

Because our london object is an instance of Condo, and our Condo implementation file imports our protected method, the london object DOES actually respond to the marketValue method. As such, the above code will successfully compile.

Along with categories, we also have extensions. They serve a similar purpose to categories in that they allow you to add methods to a class outside of that class’s main files, the difference being that you don’t use a separate interface and implementation file to define those methods. Instead, you must implement the extension’s API in the main class’s .m file (not in the interface, or .h, file).

Much like categories, we can use extensions to declare private methods. In an implementation file of House, there is a section that says @interface House () and below there is the main implementation part of the implementation file which reads @implementation House.

We declare extensions in the same place we would declare an instance variable - between the @interface House () and @end tags. There, we could have:
-(NSInteger) marketValue {
    return [self currentListedPrice];
}

Since the method isn’t declared in the header, it’s not actually visible to other classes. We would need to call it from another method that is publicly visible (declared in the .h file).