What do I need?
@required
- Mac OS X 10.6+
- XCode 4.2+
@optional
- Device with iOS 4.0+
- Paid iOS Program Membership
z, ? | toggle help (this) |
space, → | next slide |
shift-space, ← | previous slide |
d | toggle debug mode |
## <ret> | go to slide # |
c, t | table of contents (vi) |
f | toggle footer |
r | reload slides |
n | toggle notes |
p | run preshow |
@required
@optional
[array insertObject:anObject atIndex:0]; // where's C here?
// java
anObject.aMethod();
// obj-c [anObject aMethod];
// java
anObject.aMethod().anotherMethod();
// obj-c [[anObject aMethod] anotherMethod];
// java
array.add(0,object);
// obj-c [array insertObject:object atIndex:0];
interface
concept in Java.
closures
in Ruby or Javascript.@property (retain) NSString *name; ... object.name = @"Slim Shady"; NSLog(@"My name is %@",object.name);
0
, it will be automatically deallocated.How do I increase the object's reference counter?
retain
: [array retain];
init
constructors: [[NSArray alloc] init]
.How do I decrease the object's reference counter?
release
: [array release];
autorelease
: [array autorelease];
// Instanciates and increases reference counter NSOperationQueue *q = [[NSOperationQueue alloc] init]; // uses object normally [q addOperationWithBlock:^{ // do something in background }]; // decreases reference counter [q release];
autorelease
?
@interface
and @implementation
ObjectName.h
and the implementation in ObjectName.m
..m
file.#import "User.h" @interface Tweet @property (nonatomic, retain) User *author; @property (nonatomic, retain) NSDate *date; @property (nonatomic, retain) NSString *text; - (Tweet *) initWithAuthor:(User *)author text:(NSString *)text; + (NSArray *) getTweetsByAuthor:(User *)author; @end
#import "Tweet.h" @implementation Tweet @synthesize author; @synthesize date, text; // release all properties - (void) dealloc { self.author = nil; // no release here? self.date = nil; // we'll talk about that self.text = nil; // later [super dealloc]; } ...
... - (Tweet *) initWithAuthor:(User *)aUser text:(NSString *)aText { if (self = [super init]) { self.author = aUser; self.text = aText; } return self; } + (NSArray *) getTweetsByAuthor:(User *)author { // retrieve tweets ... } @end
@property (nonatomic, retain) NSString *text;
tweet.text
- (NSString *) text; - (void) setText:(NSString *)text;
@interface
@property (attributes) type name;
nonatomic
: synthesized accessors won't provide robust access to properties in a
multithreaded environment.retain
: generated setter will retain the new value (and release the previous one).
Use this for objects.assign
: generated setter will only assign the new value. Use this for scalar types.@implementation
@synthesize name;
retain
attribute, retains and releases are made by the generated accesors.
self.property = nil
in the previous dealloc
method.@property (nonatomic, retain) NSString *text;
- (void)setText:(NSString *)newText { [newText retain]; // because of retain [text release]; // because of retain text = newText; } - (NSString *)text { return text; }
+
sign+ (NSArray *) getTweetsByAuthor:(User *)author;
-
sign- (Tweet *) initWithText:(NSString *)text;
@interface
.@implementation
.(NSArray *)
, (NSUInteger)
, (int)
...*
init
initWithArg1:(type1)arg1 arg2:(type2)arg2 ...
@implementation
- (Tweet *) initWithAuthor:(User *)aUser text:(NSString *)aText { if (self = [super init]) { // always // your code here self.author = aUser; self.text = aText; } return self; // always }
Tweet *t = [[Tweet alloc] initWithAuthor:aUser text:@"Lorem ipsum"];
sections
.
section
is composed by rows
.indexPath
object will let you access them:
indexPath.section
indexPath.row
plain
and grouped
.dataSource
delegate
dataSource
delegate
User.h
@interface User : NSObject @property (nonatomic, retain) NSString *username; - (User *) initWithUsername:(NSString *)username; + (User *) userWithUsername:(NSString *)username; + (NSArray *) getUsers; @end
User.m
@implementation User @synthesize username; - (void) dealloc { self.username = nil; [super dealloc]; } - (User *) initWithUsername:(NSString *)aUsername { if (self = [super init]) { self.username = aUsername; } return self; } ...
User.m
... + (User *) userWithUsername:(NSString *)username { return [[[User alloc] initWithUsername:username] autorelease]; } @end
Tweet.h
#import "User.h" @interface Tweet : NSObject @property (nonatomic, retain) User *author; @property (nonatomic, retain) NSString *text; @property (nonatomic, retain) NSDate *date; - (Tweet *) initWithAuthor:(User *)author text:(NSString *)text date:(NSDate *)date; + (NSArray *) getTweetsByAuthor:(User *)author; @end
Tweet.m
@implementation Tweet @synthesize author, text, date; - (void) dealloc { self.author = nil; self.text = nil; self.date = nil; [super dealloc]; } ...
Tweet.m
... - (Tweet *) initWithAuthor:(User *)aUser text:(NSString *)aText date:(NSDate *)aDate { if (self = [super init]) { self.author = aUser; self.text = aText; self.date = aDate; } return self; } @end
getTweetsByAuthor:
obtains tweets from twitter api
Parsing JSON
// obtain response from the source url NSString *response = [NSString stringWithContentsOfURL: [NSURL URLWithString:url] encoding:NSUTF8StringEncoding error:&error]; ...
... NSArray *parsedResponse = [response objectFromJSONString]; for (NSDictionary *parsedTweet in parsedResponse) { NSDate *date = [formatter dateFromString: [parsedTweet objectForKey:@"created_at"]]; NSString *text = [[parsedTweet objectForKey:@"text"] stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; }
@property NSArray *users
.UITableViewDataSource
to populate the table.UITableViewDelegate
to add behavior.UITableViewDataSource
1
[self.users count]
[self.users objectAtIndex:indexPath.row]
UITableViewDelegate
[self.users objectAtIndex:indexPath.row]
@property User *user
and NSArray *tweets
.dataSource
and delegate
in the same way than the User Controller.UIWindow
)rootViewController
property.
window.rootViewController = usersViewController
would be ok...
UINavigationController
UINavigationController
UsersViewController *usersViewController = [[UsersViewController alloc] initWithNibName:@"UsersViewController" bundle:nil]; self.window.rootViewController = [[[UINavigationController alloc] initWithRootViewController:usersViewController] autorelease]; [usersViewController release];
NSOperations
and NSOperationQueues
you can easily run
code in background.
self.loading = YES; [self.tableView reloadData]; NSOperationQueue *q = [[NSOperationQueue alloc] init]; [q addOperationWithBlock:^{ NSArray *tweetsByAuthor = [Tweet getTweetsByAuthor: self.user]; // refresh the view. // this is related with the UI, so it has to run // in main thread. [[NSOperationQueue mainQueue] addOperationWithBlock:^{ self.loading = NO; self.tweets = tweetsByAuthor; [self.tableView reloadData]; }]; }]; [q release];