-
Notifications
You must be signed in to change notification settings - Fork 3
Objective C
The id
type is a pointer to any Objective-C class, which must respond to retain
and release
messages.
The new
keyword can be used instead of alloc
and init
.
[MyClass new]; // equivalent to [[MyClass alloc] init]
#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.
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.
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
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
@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