ernstsson.net
Objective-C - Minimize Mutability

Immutable classes are classes that cannot be modified after they are instantiated. This means that all ivars of the class needs to be unmodifiable. Having no moving parts, immutable classes are easier to unit test. For the same reason a system built of mainly immutable classes will be less brittle. The risk for one subsystem modifying parts of another subsystem simply disappears. Because of this it is desirable to let classes be immutable if possible.Since it is not possible to lock down the modification of ivars in Objective-C all classes are strictly speaking mutable. There are however ways to achieve the perks of immutability.

Read More


Objective-C - Minimize Accessibility

In object-oriented programming it is desireable to restrict access to data and instead exposed methods to operate on the data. This enables us to change how this data is accessed and represented without making changes to client code. This fundamental concept of encapsulation can easily be achieved in Objective-C using a few different techniques.

Read More


Objective-C - Builders

As with init methods, class factory functions gets harder to read the more parameters they have. Consider the following class.

@interface Person : NSObject
@property (nonatomic, readonly) NSString *name;
+(instancetype)personWithName:(NSString*)name;
@end

Calling this is simple

Person *person = [Person personWithName:@"Sherlock"];

When adding more parameters calling the class factory method gets increasingly harder to read. Consider the same class with this new interface and class factory method.

Read More


Objective-C - Factory Method Categories

At times there are reasons to create an instance of a class based on classes that you typically would not want to have dependencies on. A typical example would be to create a view class based on a model class. The view should be separate from the model. This code usually ends up in big controller classes. Take the example of showing a list of persons in a table view. A table view cell needs to be created based on a person model class.

@implementation CustomViewController

-(UITableViewCell *)tableView:(UITableView *)tableView
        cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    Person *person = [[self repository] personAtIndex:[indexPath row]];
    CustomTableViewCell *cell = [CustomTableViewCell cell];
    [cell setTitle:[person name]];
    [cell setSubTitle:[person phoneNumber]];
    [cell setImage:[person image]];
    return cell;
}

@end

The construction of the custom table view cell can be extracted into a separate function responsible of creating the cell based on the data in the person class.

@implementation CustomViewController

-(UITableViewCell *)tableView:(UITableView *)tableView
        cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    Person *person = [[self repository] personAtIndex:[indexPath row]];
    return [self cellFromPerson:person];
}

-(UITableViewCell *)cellFromPerson:(Person *)person
{
    CustomTableViewCell *cell = [CustomTableViewCell cell];
    [cell setTitle:[person name]];
    [cell setSubTitle:[person phoneNumber]];
    [cell setImage:[person image]];
    return cell;
}

@end

Instead of keeping this helper factory method in the custom view controller it could be extracted into a Factory Method Category.

Read More


Objective-C - Class Factory Methods

The most common way to create instances of a class in Objective-C is to call alloc on the class. This returns an uninitialized instance that needs to be initialized with init.

[[MyClass alloc] init];

An alternative short form of this is new.

[MyClass new];

It is possible to create a new init function in order to pass parameters needed for object initialization.

-(instancetype)initWithString:(NSString *)string
{
    self = [super init];
    if (self) {
        _string = string;
    }
    return self;
}

This is then used in a similar way.

[[MyClass alloc] initWithString:@"MyString"];

There is an alternative way of letting clients create instances. Instead of calling alloc and init explicitly a class method could be used to encapsulate this.

Read More


Composite As A Language Feature

During the past work week at our client, a collague and I started to discuss the composite pattern and how it fit into a part of the system we were working on. The composite pattern is a way of treating a collection of an object in the same way as the object itself. It is typically implemented using an interface that is implemented by both the leaf and a composite where the composite is really a collection of the interface, meaning either leafs or more composites. When calling a method on the composite the method is called on every instance in the collection, eventually leading to calls on the leafs. Our problem at hand was not very interesting, trivial even. It did however spawn an unexpected discussion. What if composite was a language feature instead of a pattern? The question itself started as a joke, but being computer language geeks the idea just had to be explored.

Read More


Imagine There’s No C-Loops

It’s actually not that easy, even if you try, to imagine a world without loops in C. This is however what I have been up to recently. To be able to even start imagining this we would have to revisit recursion and tail call optimization. As mentioned in Recursive and Iterative Functions having a function call as the last instruction in a function is called a tail call. Using this for a recursive function is called tail call recursion. Although not explicitly a part of C both GCC and LLVM can optimize tail call recursions and replace these with a loop instead. If this was a part of the C standard we wouldn’t have to use loops at all. Lets rephrase.

Imagine a World With Tail Call Optimization in C

A world with tail call optimization in C would be an interesting world. In such a world following code:

void iterator(void)
{
    printf("Loop it!");
    iterator();
}

would be equivalent to this:

void iterator(void)
{
    while (1) {
        printf("Loop it!");
    }
}

Read More


Switch Elimination

A few weeks ago I wrote about Boolean Parameter Elimination, using function pointers to reduce the number of branches in a function. The same method could also be used eliminating switches. Let’s have a look at an example of a function switching on an enum parameter:

void pointMove(Point *point, Direction direction, int step)
{
    switch (direction) {
        case NORTH:
            point->x += step;
            break;
        case SOUTH:
            point->x -= step;
            break;
        case EAST:
            point->y += step;
            break;
        case WEST:
            point->y -= step;
            break;
        default:
            assert(0);
    }
    printf("Point: x=%i, y=%i\n", point->x, point->y);
}

The function pointMove operates on a Point struct changing its coordinates based on a cardinal direction enum parameter. After a direction specific instruction has been executed a common instruction, in this case printf , is executed for every direction.

Extracting Functions

An initial simple improvement to this would be extracting functions for each case:

void pointMove(Point *point, Direction direction, int step)
{
    switch (direction) {
        case NORTH:
            pointMoveNorth(point, step);
            break;
        case SOUTH:
            pointMoveSouth(point, step);
            break;
        case EAST:
            pointMoveEast(point, step);
            break;
        case WEST:
            pointMoveWest(point, step);
            break;
        default:
            assert(0);
    }
    pointPrint(point);
}

Each block of code in the switch is now extracted into a function. The common code at the end has also been extracted:

static void pointMoveNorth(Point *point, int step)
{
    point->x += step;
}

static void pointMoveSouth(Point *point, int step)
{
    point->x -= step;
}

static void pointMoveEast(Point *point, int step)
{
    point->y += step;
}

static void pointMoveWest(Point *point, int step)
{
    point->y -= step;
}

void pointPrint(Point *point)
{
    printf("Point: x=%i, y=%i\n", point->x, point->y);
}

The example here is of course kept very simple with only one instruction per case in the switch. It is sadly not uncommon to see code where each case in the switch contains tens or even hundreds of lines of code. In this simple example the code complexity after the change is roughly the same with each case still containing one line. For more complex functions this restructuring is the least one should do.

Read More


Recursive and Iterative Functions

Using recursive functions is in my opinion a very elegant way of solving a lot of problems, given that the language and environment is made for it. Unfortunately C is not. Especially in embedded environments or in limited operating systems, recursion can be harmful. In this post we will have a look at recursion in C and how to avoid it.

Recursive Functions

Let’s consider the following implementation of a function returning the factorial of a number:

unsigned long long factorial(unsigned long long n)
{
    if (n == 0 || n == 1) {
        return n;
    }

    return factorial(n - 1) * n;
}

The factorial function calls itself to calculate the factorial for n-1 and then multiplies this with n. For example, since the factorial of 5 is 1*2*3*4*5 this function asks itself to calculate the factorial of 4 (1*2*3*4) then multiplies this with 5. When we get down to calculate the factorial of one, we simply return one.

The effect of this function is that we have a recursively growing stack that depends on the input. Since we need to wait for the call to factorial of n-1 before we multiply this with n, we need to store an instance of the factorial function together with an instance of n for each recursion. This uses up a lot of stack. In many embedded systems this is unwanted since stack sizes might be of static size and can thus simply run out of memory. Even if we do have enough memory for our problem, static stack size configuration for code using recursive functions is hard. This especially problematic if the number of recursions change based on some external input. Of course, in non-embedded systems with dynamic stacks it is still desirable to save memory if possible.

Read More


Boolean Parameter Elimination

One commonly used anti-pattern increasing function complexity reported by Arqua is the use of boolean parameters. Let’s have a look at an example of this:

int calculateSum(int a, int b, int log)
{
    int sum = a + b;
    if (log) {
        printf("result:%i\n", sum);
    }
    return sum;
}

The function calculateSum is used like this:

int main(void)
{
    calculateSum(4, 5, TRUE);
    calculateSum(3, 2, FALSE);
}

Here the first call to calculateSum is logging and the second is not. The parameter log controls if the function should log or not. Of course this is a simplified example, containing only one line doing the calculation. More often the calculation is done over many lines with logging embedded between these lines:

int calculateComplexThings(int a, int b, int log)
{
    //Do initial calculations

    ...

    //Log a value
    if (log) {
        printf("result:%i\n", value);
    }

    //Do more calculations

    ...

    //Log a value
    if (log) {
        printf("result:%i\n", value);
    }

    //Calculate even more

    ...


    return value;
}

Read More