Category Archive: Cocoa

Using double pointers with functions

Obviously is a technique that is not heavily used, but it comes handy some times. Methods in objective-C can return up to one argument. Double pointers can help you “return” more than one.

How is this useful,

For example, two methods:

// interface
- (UIImage*)logoForTag:(int)aTag;
- (NSString*)titleForTag:(int)aTag;
 
// implementation
- (UIImage*)logoForTag:(int)aTag
{
    switch (aTag) {
        case 0:
            return [UIImage imageNamed:@"0"];
            break;
        case 1:
            return [UIImage imageNamed:@"1"];
            break;
//..    
        default:
            break;
    }    
    return nil;
}
- (NSString*)titleForTag:(int)aTag
{
    switch (aTag) {
        case 0:
            return [NSString stringWithFormat:@"0"];
            break;
        case 1:
            return [NSString stringWithFormat:@"1"];
            break;
            //..    
        default:
            break;
    }    
    return nil;
}

We passing the same tag and we are doing the same comparison with the switch statement.
It already obvious that things could be different, THIS IS A HINT. you see duplicated code.

So, we want one method that does that:

- (void)setTitle:(NSString*)title andImage:(UIImage*)image forTag:(int)aTag
 
// calling the method
    NSString *string = nil;
    UIImage *image = nil;
 
    [singlePointerMethod setTitle:string andImage:image forTag:0];
 
    NSLog(@"%@,%@",string ,image);
    // NULL , NULL

But wait, this does not work :) Why? Well, passing a pointer to your function it can only modify the pointer that is pointing to. In this case nil, the objects have not ben allocated yet. We cannot return the change to the caller.

So the solution of double pointers or “pointer to pointer”. Passing a pointer to a pointer to the function we can modify the pointer to point to another object. This allows us to pass a pointer to a function and modify it.

// interface
- (void)setTitle:(NSString**)title andImage:(UIImage**)image forTag:(int)aTag
 
// implementation
- (void)setTitle:(NSString**)title andImage:(UIImage**)image forTag:(int)aTag
{
    switch (aTag) {
        case 0:
            *image = [UIImage imageNamed:@"0"];
            *title = [NSString stringWithFormat:@"0"];
            break;
        case 1:
            *image = [UIImage imageNamed:@"1"];
            *title = [NSString stringWithFormat:@"1"];
            break;
            //..    
        default:
            break;
    }        
}
 
// usage
    NSString *string = nil;
    UIImage *image = nil;
 
    [singlePointerMethod setTitle:&string andImage:&image forTag:0];
 
    NSLog(@"%@,%@",string ,image);
    // log 0,<UIImage: 0x685dc10>

Regular expression… Postcode (UK)

You can do so much with regular expressions that it becomes one of the most attractive programming tools. I guess you can avoid them (I am not sure how) and extract your information from a text without them, but it will be a painful procedure.

Well this article is not about explaining them, is more like… hmm… Beat it and I will reconsider:

The most common examples where are I use them are:

  1. Extracting information from a long piece of text.
  2. Validating an input field.

The first one is fairly straight forward, you have a text and you want find something in particular, such as matching a word, a value and so on…

The other one, is the main reason of the article.

You often have a textfield for the user to enter a value. How do you validate the input? You cannot iterate through the characters and it would be very complex. Consider an example where a textfield accepts only postcodes (it is like the MOST sensible paradigm I can give)

Here is the format of the british postcodes:
A9 9AA, A99 9AA, AA9 9AA, AA99 9AA, A9A 9AA, AA9A 9AA

How will you do that? If you can do it without regular expressions I would be amazed… I have not checked the processing time, but I am happy to do so if you think you can do it faster.

  1. Yeah clearly the first one needs to be a letter
  2. We also know that it ends with a number followed by two letters. Cool. (9AA)

What about the rest:

  1. Then it could be a letter or a number (AA9 9AA , A9 9AA)
  2. Then it could be a space, or a letter or a number (A9_9AA, A9A 9AA , AA99 9AA)
  3. Then it could be a space, or a letter or a number (AA9_9AA , AA9A 9AA , AA99 9AA)
  4. Then it could be a space (AA9A_9AA)

Think about it so many combinations.

The following expression does it for you…

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^([A-Z])([A-Z]|[0-9])?([0-9]|[A-Z])?([0-9]|[A-Z])([\\s]*)[0-9][A-Z][A-Z]$"
    options:NSRegularExpressionSearch | NSRegularExpressionCaseInsensitive
       error:nil];
 
// search for matches
NSUInteger numberOfMatches = [regex numberOfMatchesInString:[textField text]
       options:0 range:NSMakeRange(0, [[textField text] length])];
 
// if it's a postcode enable the button
// else disable it
if (numberOfMatches>0)    
{
// found a match do something
// maybe enable the done button
}
else
{               
// did not found a match do something else
// maybe disable the done button
}

So much power... formal definitions, seriously you cannot beat that…

Rasterizing a UIView

I was doing some work with parsing and visualising SVG files but the views ended up having lots of paths and a lot of memory was consumed. So the idea was to convert the UIView to an image … :)

 
// Doing work to generate the SVG in the schematics view;
// At the end there was no reason to keep all these (SVGView)subviews 
// ******* Rasterize ************
// Create an image from the view
 
    UIGraphicsBeginImageContext(schematicsView.frame.size);
    [schematicsView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
 
// Remove the SVG views to release the memory.
    for (SVGView *view in SVGReferences) 
        [view removeFromSuperview];
 
// Add the image that was created before as a subview
    [self.view addSubview:[[[UIImageView alloc] 
                            initWithImage:viewImage] autorelease]];

I swear pure awesomeness!!! :)

Checking for decimal points?

To check if a number has decimal points you can do the following:

if (floor(value) != value){
// it has decimal points
}

Checking for Null?

To check if a primitive data type is null you can do the following:

if (value != value){
// then is null
}

NSCoder + NSKeyedArchiver

This post is a simple example of NSCoder and NSKeyedArchiver to save and restore the data of an instance.

First of all we need to create our object, in this case an object “Person” with three properties (name, surname, age). The interface looks like normally.

#import <Foundation/Foundation.h>
@interface Person : NSObject { }
@property (retain) NSString *firstName;
@property (retain) NSString *lastName;
@property int age;
@end

The implementation needs some additional code. We need to implement the NSCoding protocol, which means two additional methods. (initWithCoder: and encodeWithCoder:)

#import "Person.h"
@implementation Person
@synthesize age,firstName,lastName;
-(id)initWithCoder:(NSCoder*)decoder{
    if ((self = [super init])) {
        firstName = [decoder decodeObjectForKey:@"firstName"];
        lastName  = [decoder decodeObjectForKey:@"lastName"];
        age           = [decoder decodeIntForKey:@"age"];
    }
    return self;
}
-(void)encodeWithCoder:(NSCoder*)encoder{
    [encoder encodeObject:firstName forKey:@"firstName"];
    [encoder encodeObject:lastName forKey:@"lastName"];
    [encoder encodeInt:age forKey:@"age"];
}
@end

Once we implement the protocol, saving will look like this:

// Save method
// We initialise our object and set the values
Person* p1 = [[[Person alloc] init] autorelease];
p1.firstName = [firstNameTextField stringValue];
p1.lastName  = [lastNameTextField stringValue];
p1.age       = [ageTextField intValue];
 
// We initialise our NSMutableData
NSMutableData *sData = [[NSMutableData alloc] init];
/*And our NSKeyedArchiver initialised to encode stream and version 
information into a given mutable data object.*/
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] 
                      initForWritingWithMutableData:sData];
// Then we encode our object for a key of our choice
[archiver encodeObject:p1 forKey:@"person"];
[archiver finishEncoding];
 
// Finally we can write out the data      
[sData writeToURL:fileURL atomically:YES];

Restoring is the other way around:

// Restore method
NSMutableData *rData = [[NSMutableData alloc]
                         initWithContentsOfURL:locationOfTheFile];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]
                         initForReadingWithData:rData];
 
// Initialise the object and use the unarchiver to set the values
Person* p1 = [[[Person alloc] init] autorelease];
p1 =  [unarchiver decodeObjectForKey:@"person"];
 
// set the value on the textfields
[firstNameTextField setStringValue:p1.firstName];
[lastNameTextField setStringValue:p1.lastName];
[ageTextField setStringValue:
                 [NSString stringWithFormat:@"%i",p1.age]];

Here is the source code of the above example with NSSavePanel and NSOpenPanel.

Enumerating collections

This post is describes techniques to enumerate your objects in a data collection, in this case an NSArray.

Using a typical for loop.

for (int i=0; i&lt;=[myArray count]; i++){
id myObject = [myArray objectAtIndex:i];
// do something with the object
}

Using the NSEnumerator.

NSEnumerator * enum = [myArray objectEnumerator];
while (id myObject = [enum nextObject]){
// do something with the object
}

A much more concrete example can be found here.

Using Fast enumeration.

for (id myObject in myArray) {
// do something with the object
}

Using makeObjectsPerformSelector which is not considered as a different method but it could be very handy in some cases:

[newArray makeObjectsPerformSelector:@selector(doSomething)];

Which is equivalent to:

for (id myObject in myArray) {
[myObject performSelector:@selector(doSomething)];
}

Notes to take under consideration:

  • The id could be replaced with a type.
  • Enumerating mutable collection can raise exceptions
  • Fast enumeration is faster than the others, According to Apple “The enumeration is considerably more efficient than, for example, using NSEnumerator directly.” so is worth checking it out.
  • You can use this on your own collection classes by implementing the NSFastEnumeration protocol.
  • For makeObjectsPerformSelector read here for some insights

More information here

Memory Management Part 1



Developing applications requires memory management. In this case, Apple provides a garbage collector for the Mac applications but not for the iPhone. From my point of my I found no reason at all, to avoid using the garbage collector and I would love to know if you think otherwise.

So let’s start: Retain count – Retain – Release

So every object has a retain count. This is an integer property of each object. For example

myObject *p = [[myObject alloc] init];  // count is now set to 1.
[p retain];  // count is now set to 2.
[p release]; // count is now set to 1.
[p release]; // count is now set to 0.

The moment you allocate an object the retain count becomes 1. If you would like to share this object to other objects you will need to retain the object. The retain method will increase the counter by 1. In case you want to decrease the count you can do it using the release method.

Note: If the count is 0 then the object is freed.

Ownership
You own an object when you alloc it, copy it or new it. If you own an object you need to release it. Consider an NSString

NSString *example = [[NSString alloc] initWithString:@"someText"];  
 // use the above string in your code
[example release]; // once you finish using it, you need to release it.

If you do not own an object then you are not responsible for releasing it unless you have explicitly retained it. Consider an NSString stringWithString

NSString *example = [NSString stringWithString:@"someText"];

Which is equal to:

NSString *example =
 [[[NSString alloc] initWithString:@"someText"] autorelease];

Autorelease

What if you want to have a method that returns an NSString?

-(NSString*)returnString{
NSString *stringToReturn = [[NSString alloc] initWithString:@"hello"];
// if you release it the string will be deallocated
// and the application will crash.
// If you don't release it then you will have a leak.
return stringToReturn;
}

So what can we do? We can call the autorelease method which simply indicates that the object will be released in the future.

-(NSString*)returnString{
NSString *stringToReturn = [[NSString alloc] initWithString:@"hello"];
[stringToReturn autorelease];
return stringToReturn;
}

Autorelease Pool
Every time you call the autorelease method from an object, is added to the outer-most autorelease pool. When the pool is release or drained, it simply sends release to all the objects in the pool. More precisely:

// create your own little autorelease pool
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// these objects get added to the autorelease pool you created above 
NSString  *string1 = [self returnString];
NSString  *string2 = [self returnString];
// use the above strings ... ...
// they will be released when the pool is released
[pool release]; // all objects added to this pool are released

This concludes todays post :) More will come regarding the properties in Objective-C.

Macros

Clearly nothing special but I am using them a lot when I write code. They called macros, and they will speed up your development for sure. Instead of writing all the time the same code (which is usually long), you can write your own macro, using a name of your choice.

Here is a simple example:

[[NSUserDefaults standardUserDefaults] integerForKey:(x)]

You can write your macro:

#define UDSI(x) [[NSUserDefaults standardUserDefaults] integerForKey:(x)]

Where UDSI is the name of the macro, in this case UserDefaults standardUserDefaults integerForKey and call it  

UDSI(@"keyName");

You can also have multiple arguments:

#define NSS(str, ...) ((NSString *)[NSString stringWithFormat:(str), ##__VA_ARGS__])
NSString * geoString = MString(@"%@-%@",object1,object2);

Here, there are two links with macros: 1 & 2
You can find more if you google, but you can always write your own ;)

Stacks and Queues

I usually find these two simple data structures (Stack and Queues) more than useful… So using a NSMutableArray we can code their behaviour quite easily.

So here you go:

The Queue

@interface NSMutableArray (CPQueue)
- (void)add:(id)object;
- (id)remove;
- (id)first;
- (id)last;
@end
 
@implementation NSMutableArray (CPQueue)
- (void)add:(id)object{
    if(object) [self addObject:object];
}
 
- (id)remove{
    id theResult = nil;
    if([self count]){
        theResult = [[[self objectAtIndex:0] retain] autorelease];
        [self removeObjectAtIndex:0];
    }
    return theResult;
}
 
- (id)first{
    return [self objectAtIndex:0];
}
 
- (id)last{
    return [self lastObject];
}
@end

The Stack

@interface NSMutableArray (CPStack)
- (void)push:(id)object;
- (id)pop;
- (id)top;
@end
 
@implementation NSMutableArray (CPStack)
- (void)push:(id)object{
    if(object) [self addObject:object];
}
 
- (id)pop
{
    id theResult = nil;
    if([self count])
    {
        theResult = [[[self lastObject] retain] autorelease];
        [self removeLastObject];
    }
    return theResult;
}
 
- (id)top
{
    return [self lastObject];
}
@end