Objective-C – Strings, Property attributes and Dates

I am learning Objective-C. This post contains some Objective-C trivia which I picked up over the last few weeks.

Concatenating Strings

In Objective-C, NSString class represents strings. Concatenating two strings is not easy. To ease the pain, there is a NSMutableString class. It has an append method. The StackOverflow post summarises the different methods available to concatenate strings. Usually, we have problems with XML strings which run into multiple lines. The example below shows an easy way to concatenate strings broken into multiple lines.

NSString* postBody = {
    @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
    "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
    " <soap:Body>"
    "  <WebServiceMethod xmlns=\"\">"
    "   <parameter>test</parameter>"
    "  </WebServiceMethod>"
    " </soap:Body>"
    "</soap:Envelope>";

Attributed Strings

NSAttributedString and NSMutableAttributedString class is used to set text attributes to the string. For example, consider displaying the text: Seats\n%d. The word Seats should appear as bold. Objective-C code to do that is shown below.

NSMutableAttributedString *seatText = 
    [[NSMutableAttributedString alloc] initWithString:
    [NSString stringWithFormat:@"Seats\n%d", seats]];
[seatText addAttribute:NSFontAttributeName 
        value:[UIFont boldSystemFontOfSize:25.0F]
        range:NSMakeRange(0,5)];
return seatText;

ARC and property attributes

ARC stands for Automatic reference counting. With ARC, the compiler takes care of reference counts of an object. When the reference count of an object reaches zero, the object is no longer in use. And can be deallocated from memory. To retain an object reference, we define the property with a strong reference.

@property (strong, nonatomic) UIButton *button;
button = [UIButton buttonWithType:UIButtonTypeCustom];

The above code ensures that the allocated button is retained. In some cases, there is a parent-child relation between objects. For example, when objects are added to array or when subviews are added to view. In such cases, a weak reference is sufficient. In the code below, the addSubview method adds a reference count to keep the object in memory.

@property (weak, nonatomic) UIButton *button;
button = [UIButton buttonWithType:UIButtonTypeCustom];
[self addSubview:button];

Sometimes, the parent object is NOT strongly referenced. In that case, the copy attribute ensures that the object is not released.

@property (copy, nonatomic) UIButton *button;
button = [UIButton buttonWithType:UIButtonTypeCustom];
[self addSubview:button];

Atomic and Non-atomic property attribute deserves attention. Atomic property attribute is the default. If a property is atomic, only one thread can access the object. Atomic properties are slow. Non-atomic property attribute improves performance. Because now, multiple threads can access the object. Objective-C has a lot of optimisation techniques for the advanced developer.

Composing Dates

Composing dates involves using NSDate, NSDateComponent and NSCalendar. The typical way to format dates in Objective-C is shown below.

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"dd-MMM-yyyy"];
NSString formattedDate = [formatter stringFromDate:[NSDate date]];

To compose a date, use the NSDateComponent class.

+(NSDate *)getDate:(int)day month:(int)month year:(int)year
{
    NSCalendar *calendar = 
            [[NSCalendar alloc] 
            initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *components = [[NSDateComponents alloc] init];
    [components setYear:year];
    [components setMonth:month];
    [components setDay:day];
    return [calendar dateFromComponents:components];
}

As you can see, composing a date object is not simple enough. So, wrap the code in an utility class with static methods. Below code show how to get the day, month and year components from a NSDate object.

+(NSDateComponents *)getComponents:(NSDate *)date
{
    NSCalendar* calendar = [NSCalendar currentCalendar];
    NSDateComponents* components = 
        [calendar components:NSYearCalendarUnit|
                            NSMonthCalendarUnit|
                            NSDayCalendarUnit 
                    fromDate:date];
    return components;
}

And here is the usage of DateHelper class.

NSDateComponent *dateComponents = 
    [DateHelper getComponents:[NSDate date]];
int day = dateComponents.day;
int month = dateComponents.month;
int year = dateComponents.year;

NSTimer

The NSTimer class creates a timer with the scheduledTimerWithTimeInterval static method.

NSTimer *timer = [NSTimer   scheduledTimerWithTimeInterval:1.0
                            invocation:@selector(callbackFunction)
                            repeats:YES];

Stop the timer using the invalidate method.

[timer invalidate];
timer = nil;

An important point to note. The thread that creates the timer and invalidates the timer should be the same. Preferably the UI thread. If a different thread calls the invalidate method, then the timer does not stop.

Related Posts

Leave a Reply

Your email address will not be published.