Albert Mata

About Software Development

Swift: Initializers

There are some basic rules for initializers in Swift:

Rule 1. An initializer has to set values for all properties that don’t have a value yet. Otherwise it won’t compile. It can set them using the values for its arguments or some calculated ones.

class MyClass {
    let myConstant: Int
    var myFirstProperty: Int
    var mySecondProperty = 78

    init(myFirstProperty: Int) {
        self.myFirstProperty = myFirstProperty
        self.myConstant = 42
    }
}

Rule 2. In a subclass, an initializer has to firstly set values for own properties (as long as they don’t have a value yet); secondly call a superclass’ designated initializer; and finally reset values for inherited properties if desired. This order is mandatory, otherwise it won’t compile.

class MySubclass: MyClass {
    var myThirdProperty: Float

    init(myThirdProperty: Float) {
        self.myThirdProperty = myThirdProperty
        super.init(myFirstProperty: 10)
        mySecondProperty = 88
    }
}

Rule 3. A class can have as many initializers as desired, both designated and convenience ones, although classes tend to have very few designated initializers, and it is quite common for a class to have only one. Convenience initializers have to a) be marked with the convenience modifier and b) call other convenience initializers or a designated initializer in the same class. Only a designated initializer can (and has to) call a superclass’ designated initializer.

class MyClass {
    let myConstant: Int
    var myFirstProperty: Int
    var mySecondProperty = 78

    init(myFirstProperty: Int) {
        self.myFirstProperty = myFirstProperty
        self.myConstant = 42
    }

    convenience init() {
        self.init(myFirstProperty: 4)
    }
}

Paper: The Null Object Pattern

Now that Apple has announced their new programming language (Swift) and that this language takes a pretty different approach about how null values behave compared to Objective-C, I’ve thought it was an excellent moment to read the paper The Null Object Pattern by Bobby Woolf (1996). According to this design pattern, an object A can communicate with another object B and not worry about whether that object B is or is not null. So, object A will not need to be constantly checking for nullity.

I’ve specially liked these paragraphs:

The Null Object pattern describes how to develop a class that encapsulates how a type of object should do nothing. Because the do nothing code is encapsulated, its complexity is hidden from the collaborator and can easily be reused by any collaborator that wants it. The key to the Null Object pattern is an abstract class that defines the interface for all objects of this type. The Null Object is implemented as a subclass of this abstract class. Because it conforms to the abstract class’ interface, it can be used any place this type of object is needed.

Use the Null Object pattern when you want clients to be able to ignore the difference between a collaborator which provides real behavior and that which does nothing. This way, the client does not have to explicitly check for nil or some other special value.

NullScope is a class in the NameScope hierarchy in VisualWorks Smalltalk. A NameScope represents the scope of a particular set of variables. What kind of variable it is (global, class level, or method level) defines what kind of NameScope it will use. For example, a StaticScope is assigned to global and class variables and a LocalScope is assigned to instance and temporary variables. Every scope has an outer scope. This is used to access variables whose scope is greater than the current level. It allows the compiler to warn the programmer if he is declaring a variable with the same name as another variable which has already been declared (usually in an outer scope). Thus NameScopes form a tree, with the global scope at the root and branches for class scopes that contain branches for method scopes. However, since all scopes have an outer scope, what is the global scope’s outer scope? It is a NullScope, a scope which never contains any variables. When looking for a variable declaration, each scope keeps looking in its outer scope until either it finds the declaration or until it hits a NullScope. NullScope knows to stop the search and answer that the variable apparently has not been declared (within the scope of the code that initiated the search). This could be handled as a special case in StaticScope, that if it is the global scope, then it should expect its outer scope to be nil, but the special case is coded more cleanly in the special class NullScope.

The paper: http://www.cs.oberlin.edu/~jwalker/refs/woolf.ps

Swift: Scala Notes

In September 2012, I enrolled in the course Functional Programming Principles in Scala given by Martin Odersky at Coursera. In that course I learnt about functional programming and how it can be effectively combined with object-oriented programming. I enjoyed that course a lot, so I highly recommend it. And now that Apple developers have Swift on the table and that in my opinion Swift has quite a few of things in common with Scala, I’ve compiled all my notes from that course in a single document, accessible here.

Quote: Lewis Carroll (1)

“Well, in our country,” said Alice, still panting a little, “you’d generally get to somewhere else -if you run very fast for a long time, as we’ve been doing.”

“A slow sort of country!” said the Queen. “Now, here, you see, it takes all the running you can do, to keep in the same place. If you want to get somewhere else, you must run at least twice as fast as that!”

Through the Looking-Glass and What Alice Found There, Lewis Carroll (Macmillan, 1871)

I felt a bit like Alice when Apple announced Swift yesterday. Two hours later, I was already reading The Swift Programming Language book and playing with Xcode 6. If it takes all the running you can do to keep in the same place, there’s not much else we can do, right? :)

Objective-C: Warnings in Xcode

A quick way to enable all possible warnings in Xcode consists in going to Build Settings > Other Warning Flags and adding one of this options:

  • -Wall to add a quite complete subset of warnings “that the developers [of the compiler] have high confidence in both their value and a low false-positive rate.”

  • -Wextra to add some extra “warnings that are believed to be valuable and sound (i.e., they aren’t buggy), but they may have high false-positive rates or common philosophical objections.”

  • -Weverything to add “an insane group that literally enables every warning in Clang. Don’t use this on your code. It is intended strictly for Clang developers or for exploring what warnings exist.”

All the quoted parts are by Chandler Carruth. Personally, I think best option is adding -Wall and -Wextra and then maybe adding or removing some specific warnings on a one by one basis using -Wunused-variable (to add) or -Wno-unused-variable (to remove).

If we then want to disable a warning temporarily we can use #pragma directives:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"

// this code will ignore unused variable warnings

#pragma clang diagnostic pop

Finally, some programmers like to treat warnings as errors. This can be achieved with these flags:

  • -Werror to turn warnings into errors.

  • -Werror=foo to turn a specific warning into an error.

  • -Wno-error=foo to turn a specific warning into a warning again (in case -Werror has been specified).

Objective-C: Properties in Categories

Not a big fan of this kind of hacks, but having the option to add a property to a category can be extremely handful sometimes. This is probably one of the cleanest ways to do it:

@interface UIView (MyCategory)

@property (nonatomic, copy) NSString *myProperty;

@end
#import <objc/runtime.h> // additional required import

@implementation UIView (MyCategory)

- (void)setMyProperty:(NSString *)myProperty
{
    objc_setAssociatedObject(self, @selector(myProperty), myProperty, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)myProperty
{
    return objc_getAssociatedObject(self, @selector(myProperty));
}

@end

The second argument for both methods requires a void *. This is usually done by using the memory address of a static const char or similar, but using @selector(myProperty) removes the need for that extra constant.

Quote: Erica Sadun (4)

Take care when using the CGColor property of UIColor instances. ARC may assume you won’t use the UIKit color any further after you assign CGColor to a variable. This can raise an exception. Always retain and release Core Graphics properties you assign to variables, even if you extract them from UIKit objects.

iOS Drawing, Practical UIKit Solutions, Erica Sadun (Addison-Wesley, 2014)

Book: Graphics and Animation on iOS

I’ve just finished reading the book Graphics and Animation on iOS by Vandad Nahavandipoor (O’Reilly, 2011). Not exactly one I would recommend. To be fair, its best point is it is short enough to be read in not more than two or three hours. I’ve wanted to read it as I’m doing some work with Core Graphics these days, but this is truly a very basic and introductory book.

More information: http://shop.oreilly.com/product/0636920020356.do

Quote: Erik Buck & Donald Yacktman (1)

It can’t be said enough times that coupling is the enemy. It is ironic that inheritance is simultaneously one of the most powerful tools in object-oriented programming and one of the leading causes of coupling. In fact, there is no tighter coupling than the relationship between a class and its inherited superclasses. Many of the patterns described in this book exist in part to reduce the need to create subclasses. The general rule is that when there is an alternative to inheritance, use the alternative.

Cocoa Design Patterns, Erik Buck & Donald Yacktman (Addison-Wesley, 2009)

Book: Core Data. Data Storage and Management for iOS, OS X, and iCloud

I’ve just finished reading the book Core Data. Data Storage and Management for iOS, OS X, and iCloud by Marcus Zarra (The Pragmatic Programmers, 2013). And it’s a really remarkable book. It’s that kind of book where you read a paragraph and you think “oh, this makes a lot of sense now, I finally understand this… but then, what about the situation when this and that happen?” And you keep reading and immediately find the answers for the questions you’ve just thought about. Really, this book is that good.

As the only small negative thing to say, I feel most developers (specially iOS developers) can totally skip the last three chapters. But the first eight ones and the two appendixes are pure gold.

More information: http://pragprog.com/book/mzcd2/core-data

Quote: Marcus Zarra (3)

Core Data has several logging levels that we can turn on to watch all of the SQL calls that are generated during an application’s life cycle. There are currently three levels to this debugging log, with level 1 being the least chatty and level 3 being the most chatty. We can set this debug output by adding the runtime parameter com.apple.CoreData.SQLDebug to our application and pass along with it the level we want to be set.

In addition to the Core Data debug setting, we can also turn on an additional setting to watch all of the chatter between Core Data and iCloud. That additional setting is com.apple.coredata.ubiquity.logLevel. For an unknown reason, this logging code responds only to level 3.

Core Data. Data Storage and Management for iOS, OS X, and iCloud, Marcus Zarra (The Pragmatic Programmers, 2013)

Objective-C: Entity Inheritance in Core Data

When using entity inheritance in databases there are two main possible implementations. Assuming this structure:

ParentEntity <att1, att2>
FirstSubentity <att3, att4>
SecondSubentity <att5, att6>

First implementation in tables consists in creating one table for each entity, as follows:

ParentEntity <id, att1, att2>
FirstSubentity <id, idParent, att3, att4>
SecondSubentity <id, idParent, att5, att6>

And second implementation consists in flattening the structure, creating one large table that includes all the properties for the parent entity as well as its children:

SingleEntity <id, att1, att2, att3, att4, att5, att6>

First approach doesn’t waste space, but it needs join operations every single time all the information for FirstSubentity or SecondSubentity is requested. Second approach doesn’t need any join, but it wastes a lot of space as it leads to a wide and tall table with many NULL values.

Core Data uses the second approach. It’s good to keep that in mind and avoid treating entity inheritance as an equal to object inheritance, as that could cause a performance penalty.

Quote: Marcus Zarra (2)

Every time an NSFetchRequest is executed, it hits the disk. This is an important point to keep in mind when we are working with NSManagedObject objects. If we are doing joins, adding objects to a relationship, and so on, it might seem easier and cleaner to perform an NSFetchRequest to check whether the object is already in the relationship or check for a similar function, but that action can hurt performance significantly. Even if we have all the relevant objects in memory, an NSFetchRequest is still going to hit the disk. It is far more efficient for us to use that NSPredicate against a collection that is already in memory.

Core Data. Data Storage and Management for iOS, OS X, and iCloud, Marcus Zarra (The Pragmatic Programmers, 2013)

Quote: Marcus Zarra (1)

Although it is easy to think of Core Data as a database API, we must remember that it is not and that structuring the data with data normalization may not yield the most efficient results. In many cases, denormalizing the data can yield greater performance gains.

[…]

Although the most powerful persistent store available for Core Data is a database, we must always be conscious of the fact that Core Data is not just a database. Core Data is an object hierarchy that can be persisted to a database format. The difference is subtle but important. Core Data is first a collection of objects that we use to display data in a user interface of some form and allow the user to access that data. Therefore, although database normalization might be the first place to look for performance improvements, we should not take it too far. There are six levels of database normalization, but a Core Data repository should rarely, if ever, be taken beyond the second level. There are several cases where we can gain a greater performance benefit by denormalizing the data.

Core Data. Data Storage and Management for iOS, OS X, and iCloud, Marcus Zarra (The Pragmatic Programmers, 2013)

Quote: Erica Sadun (3)

iOS 7 and Xcode 5 introduce two properties for laying out your formats with respect to a container’s bars. The topLayoutGuide and bottomLayoutGuide conform to the UILayoutSupport protocol, establishing offsets for view controllers whose views may extend behind parent bars. At the time of writing this book, you must assign those properties to local variables to refer to them in your format strings.

iOS Auto Layout Demystified, Erica Sadun (Addison-Wesley, 2013)

Quote: Erica Sadun (2)

To remove an equivalent constraint, you can use a method that compares constraints and removes one that mathematically matches the one you pass. Alternatively, you can tag constraints (using a class category) so you can find them and remove them at a future time. Removing constraints plays a major role in Auto Layout. Whenever you refresh a layout —most commonly when a device rotates— you need to remove invalid constraints and replace them with fresh rules.

Knowing whether your constraints will be static (used for the lifetime of your view) or dynamic (updated as needed) helps you decide which approach you need. If you think you might need to remove a constraint in the future, either hold on to it via a local variable so that you can later remove it from your view or implement workarounds that let you search for the constraint at a later time.

iOS Auto Layout Demystified, Erica Sadun (Addison-Wesley, 2013)

Quote: Erica Sadun (1)

Auto Layout is essentially a linear equation solver that attempts to find a satisfiable geometric expression of its rules. When its equations produce too many solutions, you end up with underconstrained ambiguous layout. When its equations cannot produce any solution, you know that constraints are in conflict.

iOS Auto Layout Demystified, Erica Sadun (Addison-Wesley, 2013)

Book: NSHipster: Obscure Topics in Cocoa & Objective-C

I’ve just finished reading the book NSHipster: Obscure Topics In Cocoa & Objective-C by Mattt Thompson (NSHipster, 2013). To be sincere, I don’t think this is a must-read book. Some articles are interesting (and I say articles instead of chapters because it’s too obvious that some of the content comes directly from the author’s blog, which isn’t any bad, but at least some rewriting to remove references to “last week” and “next week” and similar things would have been appropriate) but some others are superfluous and full of empty rhetoric. And the book itself is formatted in a really poor way. So, certainly not a reading I would specially recommend. However, taking into account who the author is and all the stuff he has open sourced, buying the book was a nice way to say thanks.

More information: https://gumroad.com/l/nshipster

Objective-C: NS_ENUM & NS_OPTIONS

This is the standard way to define an enumeration in C:

enum AMGMonth {
    AMGMonthJanuary = 1, // optional to make it start at 1, otherwise it starts at 0
    AMGMonthFebruary,
    ...
    AMGMonthDecember
};

Or when some specific values are required (i.e. for options to be combined using the bitwise OR operator):

enum AMGResizing {
    AMGResizingNone            = 0,      // 00000000
    AMGResizingFlexibleWidth   = 1 << 0, // 00000001
    AMGResizingFlexibleHeight  = 1 << 1, // 00000010
    AMGResizingFlexibleUnicorn = 1 << 2  // 00000100
};

Then the new types can be used this way:

enum AMGMonth month = AMGMonthFebruary;
enum AMGResizing option = AMGResizingFlexibleWidth | AMGResizingFlexibleHeight;

This syntax is usually simplified using typedef:

enum AMGMonth {
    AMGMonthJanuary = 1,
    AMGMonthFebruary,
    ...
    AMGMonthDecember
};
typedef enum AMGMonth AMGMonth;

AMGMonth month = AMGMonthFebruary;

And it’s also possible to set the type to be used (in this example, NSInteger):

typedef enum {
    AMGResizingNone            = 0,
    AMGResizingFlexibleWidth   = 1 << 0,
    AMGResizingFlexibleHeight  = 1 << 1,
    AMGResizingFlexibleUnicorn = 1 << 2
};
typedef NSInteger AMGResizing;

But instead of all this, introduced with iOS 6 there are two new constructions to do the same:

typedef NS_ENUM(NSUInteger, AMGMonth) {
    AMGMonthJanuary = 1, 
    AMGMonthFebruary,
    ...
    AMGMonthDecember
};

typedef NS_OPTIONS(NSUInteger, AMGResizing) {
    AMGResizingNone            = 0,
    AMGResizingFlexibleWidth   = 1 << 0,
    AMGResizingFlexibleHeight  = 1 << 1,
    AMGResizingFlexibleUnicorn = 1 << 2
};

AMGMonth month = AMGMonthFebruary;
AMGResizing option = AMGResizingFlexibleWidth | AMGResizingFlexibleHeight;

Quote: Mattt Thompson (1)

Perhaps the most critical detail to keep in mind when using formatters is that they are extremely expensive to create. Even just an alloc init of an NSNumberFormatter in a tight loop is enough to bring an app to its knees. Therefore, it’s strongly recommended that formatters be created once, and re-used as much as possible. If it’s just a single method using a particular formatter, a static instance is a good strategy. If the formatter is used across several methods in the same class, that static instance can be refactored into a singleton method.

NSHipster: Obscure Topics In Cocoa & Objective-C, Mattt Thompson (NSHipster, 2013)

Objective-C: Array Filter Using Blocks

According to the Wikipedia:

In functional programming, filter is a higher-order function that processes a data structure (typically a list) in some order to produce a new data structure containing exactly those elements of the original data structure for which a given predicate returns the boolean value true.

There is a filteredArrayUsingPredicate: method in NSArray and a filterUsingPredicate: method in NSMutableArray (and similar methods in other collection classes). These methods use NSPredicate objects to filter the elements in the collection. But in some cases the cross between kind-of-SQL and kind-of-regular-expressions language used for NSPredicate can make creating a complex filter function difficult. However, it’s possible to create a predicate using its predicateWithBlock: method (and so it’s possible to filter a collection using a block):

NSArray *array = @[@1, @2, @3, @7, @8, @11, @14, @19, @20];

NSPredicate *evenNumbers = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
    NSNumber *number = (NSNumber *)evaluatedObject;
    return [number integerValue] % 2 == 0;
}];

NSArray *filteredArray = [array filteredArrayUsingPredicate:evenNumbers];
NSLog(@"%@", filteredArray); // (2, 8, 14, 20)

Actually the block definition can be changed to use NSNumber * so no additional cast operation is required:

NSArray *array = @[@1, @2, @3, @7, @8, @11, @14, @19, @20];

NSPredicate *evenNumbers = [NSPredicate predicateWithBlock:^BOOL(NSNumber *number, NSDictionary *bindings) {
    return [number integerValue] % 2 == 0;
}];

NSArray *filteredArray = [array filteredArrayUsingPredicate:evenNumbers];
NSLog(@"%@", filteredArray); // (2, 8, 14, 20)

Objective-C: Equality

Three main things are required when implementing custom isEqual: for any subclass of NSObject:

  1. Implementing a new isEqualTo__ClassName__: method that performs the meaningful value comparison.
  2. Overriding isEqual: to firstly check objects identity, then classes equality and finally objects equality.
  3. Overriding hash method, usually by XOR’ing the hash values of some or all critical properties.

In code:

@interface AMGBook

@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *author;
@property (nonatomic, strong) NSDate *publicationDate;

- (BOOL)isEqualToBook:(AMGBook *)book;

@end
@implementation AMGBook

- (BOOL)isEqualToBook:(AMGBook *)book
{
    if (!book) {
        return NO;
    }
    return [self.title isEqualToString:book.title]
        && [self.author isEqualToString:book.author]
        && [self.publicationDate isEqualToDate:book.publicationDate];
}

- (BOOL)isEqual:(id)object 
{
    if (self == object) {
        return YES;
    }
    if (![object isKindOfClass:[AMGBook class]]) {
        return NO; 
    }
    return [self isEqualToBook:(AMGBook *)object];
}

- (NSUInteger)hash 
{
  return [self.title hash] ^ [self.author hash] ^ [self.publicationDate hash];
}

@end

Paper: You and Your Research

As a short reading for this rainy Irish weekend, I’ve read the paper You and Your Research by Richard Hamming (1986). Hamming was an American mathematician whose work had many implications for computer science and telecommunications. This paper is actually the transcription of the Bell Communications Research Colloquium Seminar celebrated on 7 March 1986. In it, he talked about the required steps and efforts to go from doing good work to delivering first-class work.

I’ve specially liked these paragraphs:

Now for the matter of drive. You observe that most great scientists have tremendous drive. I worked for ten years with John Tukey at Bell Labs. He had tremendous drive. One day about three or four years after I joined, I discovered that John Tukey was slightly younger than I was. John was a genius and I clearly was not. Well I went storming into Bode’s office and said, “How can anybody my age know as much as John Tukey does?” He leaned back in his chair, put his hands behind his head, grinned slightly, and said, “You would be surprised Hamming, how much you would know if you worked as hard as he did that many years.” I simply slunk out of the office!

What Bode was saying was this: “Knowledge and productivity are like compound interest.” Given two people of approximately the same ability and one person who works ten percent more than the other, the latter will more than twice outproduce the former. The more you know, the more you learn; the more you learn, the more you can do; the more you can do, the more the opportunity —it is very much like compound interest. I don’t want to give you a rate, but it is a very high rate. Given two people with exactly the same ability, the one person who manages day in and day out to get in one more hour of thinking will be tremendously more productive over a lifetime.

Another thing you should look for is the positive side of things instead of the negative. I have already given you several examples, and there are many, many more; how, given the situation, by changing the way I looked at it, I converted what was apparently a defect to an asset. I’ll give you another example. I am an egotistical person; there is no doubt about it. I knew that most people who took a sabbatical to write a book, didn’t finish it on time. So before I left, I told all my friends that when I come back, that book was going to be done! Yes, I would have it done —I’d have been ashamed to come back without it! I used my ego to make myself behave the way I wanted to. I bragged about something so I’d have to perform. I found out many times, like a cornered rat in a real trap, I was surprisingly capable. I have found that it paid to say, “Oh yes, I’ll get the answer for you Tuesday,” not having any idea how to do it. By Sunday night I was really hard thinking on how I was going to deliver by Tuesday. I often put my pride on the line and sometimes I failed, but as I said, like a cornered rat I’m surprised how often I did a good job. I think you need to learn to use yourself. I think you need to know how to convert a situation from one view to another which would increase the chance of success.

The paper: http://www.cs.virginia.edu/~robins/YouAndYourResearch.html

Book: Effective Objective-C 2.0

I’ve just finished reading the book Effective Objective-C 2.0 by Matt Galloway (Addison-Wesley, 2013). In my opinion, one of the best Objective-C books I’ve ever read. As its subtitle exposes, the book is a collection of 52 specific ways to improve our iOS skills. These 52 items can be read independently to learn a thing or two about a topic, although it surely can be read in standard linear order as well (which is what I’ve done).

More information: http://www.informit.com/store/effective-objective-c-2.0-52-specific-ways-to-improve-9780133386967