blocks

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. 

 

 

 

 

 

iOS Questions: Pt. 1

In this (long) series of posts, I'll be posting groups of questions on iOS concepts as they come to me. I have no direction in the questions I'm choosing to answer, I'm simply going to go through notes of mine, find random questions, and answer them. If questions come up in this series that need deserve dedicated posts, I'll link to another blog post that discusses the topic more fully (think something like multithreading with GCD).

  1. Deep copy v. Shallow copy v. Assignment
    A shallow copy simply copies references to a place in memory. If object B is a shallow copy of object A, it simply copies object A's references (pointers) to objects in memory. Object B then refers to that same place in memory. Making changes to the data contained in one of the objects will impact the very same data being used by the other.

    In contrast, a deep copy makes copies of the actual data, storing it elsewhere in memory. Changing the data contained in one object will have no impact on the other.

    Assigning one object to equal another creates a pointer to a group of pointers, which point to memory. That is, if you have dictionary *A, and dictionary *B = A, then B contains a pointer to A's pointers, which point to the objects in memory. Although it will behave the same as a shallow copy, in a shallow copy, B would actually contain each pointer that A contains, still pointing to the same objects in memory. In either case, changing the values of one will change the other.
     
  2. Heaps and Stacks in iOS - how are they used?
    Almost all objects in iOS development are stored on the heap - they can be accessed globally and must be manually released and deallocated (pre-ARC). Stack objects disappear when a function returns and don't need to be manually managed. Imagine if stacks were widely used in iOS - what would happen if you needed to keep one around after the function returned? You could retain it, but after the function ended, that retain command would be pointing to a non-existent object - a dangling pointer. As a result, almost all objects are placed on the heap - the exception is blocks.

    Blocks are actually stored on the stack - that's why variables created within blocks aren't accessible outside of the block. They no longer exist when the block (which is treated like a function) ends; to continue to use them outside of the scope of the block, you must use a __block variable before entering the block. You can also create a copy of the block variable you wish to use, which actually places that copy on the heap.
     
  3. What are block variables used for?
    Using block variables (prefaced with a double underscore during declaration) is a way to access information created within a block outside of the block itself (remember that objects created within a block are stored on the stack, and as such disappear when the block exits). You could technically have an array created within a block, have an array property, and set the array property equal to the block array. However, this array is now accessible from everywhere else in the program since it's a global property - for the sake of data encapsulation, block variables are a better choice.
     
  4. What is a message in Objective-C? A Method? A selector?
    Messages and Methods are conceptually different in Objective-C but not so different practically.

    Objective-C runtime keeps a list of methods and functions it is aware of. When compiled, method names are turned into selectors (representations of the method name in memory). A function, objc_msgSend, is also called - it does a dynamic lookup, where it goes to the list of functions and finds the one we need (which is represented as a selector).

    This dynamic lookup allows us to do some interesting stuff - we can change the list at will. We can move values so that selectors point to different code than what was written. Additionally, the runtime asks objects if it recognizes methods before it actually sends a message. An object can then choose if it even wants to respond to that message.

    In short, when calling a method, there is little ambiguity - we know who is performing the action. The object did something.
    However, when we send a message, that ambiguity does exist. Something was done by the object. The emphasis is no longer on the object, but rather that “something” was done - when we send a message, we can’t be entirely sure what will respond, since dynamic lookup allows us to change certain things about our list of functions. The focus is more on the message itself.