Skip to content
Kevin Leong edited this page Jan 6, 2017 · 8 revisions

Objective-C

Objective-C runtime

References

Initializers

id

The id type is a pointer to any Objective-C class, which must respond to retain and release messages.

new keyword

The new keyword can be used instead of alloc and init.

[MyClass new]; // equivalent to [[MyClass alloc] init]

References

Properties

#import <Foundation/Foundation.h>
#import "Address.h"

@interface Person : NSObject
/**
 Defaults:
    readwrite, atomic, strong
 As opposed to:
    readonly, nonatomic, weak
 */
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) Address *address;
@end

The @synthesize keyword in the .m file is implied, and automatically generates setters and getters for each property.

Instance Variables

Similarly, the following attributes can be assigned to instance variables if the @property directive is not used:

@implementation

NSString __weak *someText;
NSString __strong *otherText; // ivars are strong by default.

@end

The atomic keyword is not supported for instance variables. Thread safety must be manually managed using locks. E.g., the @synchronized directive.

References

Constants

Header file:

#import <Foundation/Foundation.h>
#import "Address.h"

@interface Person : NSObject
/**
    extern keyword makes the constant available to other classes.

    const keyword makes the pointer immutable.

    constants are not namespaced in Objective-C.
 */
extern NSString* const PERSON_NAME_KEY;
extern NSString* const PERSON_ADDRESS_KEY;

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) Address *address;

- (id)initWithDictionary:(NSDictionary*) dict;

@end

Implementation:

#import "Person.h"

@implementation Person

NSString* const PERSON_NAME_KEY = @"name";
NSString* const PERSON_ADDRESS_KEY = @"address";

- (id)initWithDictionary:(NSDictionary *)dict {
    self = [super init];

    // Returns false if self is nil.
    if(self) {
        self.name = dict[PERSON_NAME_KEY];
        self.address = dict[PERSON_ADDRESS_KEY];
    }

    return self;
}

- (NSString *)description {
    NSArray* personDetails = @[self.name, self.address.description];

    return [personDetails componentsJoinedByString:@"\n"];
}
@end

Categories and Extensions

A category allows a class to be modularized into separate files.

Each category contains a header and implementation file, and must be imported by clients in addition to importing the header for the original class.

Extensions can only be added to a class's implementation .m file.

Extensions allow the addition of private variables and properties, and are syntatically equivalent to categories, but without the category name.

@interface MyClass : NSObject

// Only allows clients to read this property.
@property(readonly) NSString *myString;

@end

// Extension definition. Note the blank category name.
@interface MyClass()

// Exposes a writable property to the implementation only.
@property(readwrite) NSString *myString;

@end

@implementation MyClass
@end

References

Blocks

@interface Block : NSObject
- (void)doSomething;
@end

@implementation Block

- (void)doSomething {
    // Define myBlock variable of type block.
    NSString* (^myBlock)(NSString *, int) = ^(NSString* myString, int repeatCount) {
        NSMutableString *result = [[NSMutableString alloc] init];

        // Repeats myString n times.
        for(int i = 0; i < repeatCount; i++) {
            [result appendString:myString];
        }

        return result;
    };

    // Prints foofoofoofoofoo
    NSLog(@"myBlock result: %@", myBlock(@"foo", 5));

    // Prints barbarbarbarbar
    [self runBlock:myBlock];
}


- (void)runBlock: (NSString* (^)(NSString *, int)) someBlock {
    NSLog(@"%@", someBlock(@"bar", 5));
}
@end

References

Clone this wiki locally