- •C and Objective-C
- •How this book works
- •How the life of a programmer works
- •Installing Apple’s developer tools
- •Getting started with Xcode
- •Where do I start writing code?
- •How do I run my program?
- •So what is a program?
- •Don’t stop
- •Types
- •A program with variables
- •Challenge
- •Boolean variables
- •When should I use a function?
- •How do I write and use a function?
- •How functions work together
- •Local variables, frames, and the stack
- •Recursion
- •Looking at the frames in the debugger
- •return
- •Global and static variables
- •Challenge
- •printf()
- •Integer operations
- •Integer division
- •Operator shorthand
- •Floating-point numbers
- •Tokens for displaying floating-point numbers
- •The while loop
- •The for loop
- •break
- •continue
- •The do-while loop
- •Challenge
- •Getting addresses
- •Storing addresses in pointers
- •Getting the data at an address
- •How many bytes?
- •NULL
- •Stylish pointer declarations
- •Challenges
- •Writing pass-by-reference functions
- •Avoid dereferencing NULL
- •Creating and using your first object
- •Message anatomy
- •Objects in memory
- •Challenge
- •Nesting message sends
- •Multiple arguments
- •Sending messages to nil
- •Challenge
- •Challenge
- •NSMutableArray
- •Reference pages
- •Quick Help
- •Other options and resources
- •Accessor methods
- •Dot notation
- •Properties
- •self
- •Multiple files
- •Challenge
- •Overriding methods
- •super
- •Challenge
- •Object ownership and ARC
- •Creating the Asset class
- •Adding a to-many relationship to Employee
- •Challenge
- •Retain cycles
- •Weak references
- •Zeroing of weak references
- •For the More Curious: Manual reference counting and ARC History
- •Retain count rules
- •NSArray/NSMutableArray
- •Immutable objects
- •Sorting
- •Filtering
- •NSSet/NSMutableSet
- •NSDictionary/NSMutableDictionary
- •Preprocessor directives
- •#include and #import
- •#define
- •Global variables
- •enum
- •#define vs global variables
- •Writing an NSString to a file
- •Reading files with NSString
- •Writing an NSData object to a file
- •Reading an NSData from a file
- •Target-action
- •Helper objects
- •Notifications
- •Which to use?
- •Callbacks and object ownership
- •Challenge
- •Getting started with iTahDoodle
- •BNRAppDelegate
- •Adding a C helper function
- •Objects in iTahDoodle
- •Model-View-Controller
- •The application delegate
- •Setting up views
- •Running on the iOS simulator
- •Wiring up the table view
- •Adding new tasks
- •Saving task data
- •For the More Curious: What about main()?
- •Edit BNRDocument.h
- •A look at Interface Builder
- •Edit BNRDocument.xib
- •Making connections
- •Revisiting MVC
- •Edit BNRDocument.m
- •Writing init methods
- •A basic init method
- •Using accessors
- •init methods that take arguments
- •Deadly init methods
- •Property attributes
- •Mutability
- •Lifetime specifiers
- •copy
- •More about copying
- •Advice on atomic vs. nonatomic
- •Key-value coding
- •Non-object types
- •Defining blocks
- •Using blocks
- •Declaring a block variable
- •Assigning a block
- •Passing in a block
- •typedef
- •Return values
- •Memory management
- •The block-based future
- •Challenges
- •Anonymous block
- •NSNotificationCenter
- •Bitwise-OR
- •Bitwise-AND
- •Other bitwise operators
- •Exclusive OR
- •Complement
- •Left-shift
- •Right-shift
- •Using enum to define bit masks
- •More bytes
- •Challenge
- •char
- •char *
- •String literals
- •Converting to and from NSString
- •Next Steps
- •Index
Chapter 27 Your First iOS Application
You can see the views that you set up and laid out in application:didFinishLaunchingWithOptions:, but they can’t do anything yet. In fact, tapping the Insert button will crash the application because the button’s action method, addTask:, isn’t implemented yet. (That’s one of the reasons the compiler warned you about it.)
Figure 27.7 iTahDoodle object diagram
Wiring up the table view
You’ve got a table view on the screen, but it has no clue about what it should display. As a view object, the table view does not contain anything about actual data. It needs an object to act as its data source. In iTahDoodle, your table view’s data source will be the instance of BNRAppDelegate.
In BNRAppDelegate.m, update application:didFinishLaunchingWithOptions: to send a message to the table view that makes the BNRAppDelegate instance its data source:
...
// Create and configure the table view
taskTable = [[UITableView alloc] initWithFrame:tableFrame style:UITableViewStylePlain];
[taskTable setSeparatorStyle:UITableViewCellSeparatorStyleNone];
//Make this object the table view's dataSource [taskTable setDataSource:self];
//Create and configure the text field where new tasks will be typed taskField = [[UITextField alloc] initWithFrame:fieldFrame];
...
186
Wiring up the table view
In order for the table view’s data source to do its job, it must implement methods in the
UITableViewDataSource protocol. First, update BNRAppDelegate.h to declare that BNRAppDelegate conforms to this protocol:
@interface BNRAppDelegate : UIResponder <UIApplicationDelegate, UITableViewDataSource>
{
UITableView *taskTable; UITextField *taskField; UIButton *insertButton;
NSMutableArray *tasks;
}
- (void)addTask:(id)sender;
The UITableViewDataSource protocol has two required methods that BNRAppDelegate must now implement. At a minimum, a table view’s data source must be prepared to tell the table view how many rows are in a given section of the table, and what the cell in a given row should be.
Implement the callbacks accordingly:
#pragma mark - Table View management
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//Because this table view only has one section,
//the number of rows in it is equal to the number
//of items in our tasks array
return [tasks count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//To improve performance, we reconfigure cells in memory
//that have scrolled off the screen and hand them back
//with new contents instead of always creating new cells.
//First, we check to see if there's a cell available for reuse. UITableViewCell *c = [taskTable dequeueReusableCellWithIdentifier:@"Cell"];
if (!c) {
// ...and only allocate a new cell if none are available
c = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
}
//Then we (re)configure the cell based on the model object,
//in this case our todoItems array
NSString *item = [tasks objectAtIndex:[indexPath row]]; [[c textLabel] setText:item];
// and hand back to the table view the properly configured cell return c;
}
187
Chapter 27 Your First iOS Application
To test the application, add some data directly to the array at the top of application:didFinishLaunchingWithOptions:.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Attempt to load an existing to-do dataset from an array stored to disk. NSArray *plist = [NSArray arrayWithContentsOfFile:docPath()];
if (plist) {
//If there was a dataset available, copy it into our instance variable. tasks = [plist mutableCopy];
}else {
//Otherwise, just create an empty one to get us started.
tasks = [[NSMutableArray alloc] init];
}
// Is tasks empty?
if ([tasks count] == 0) {
// Put some strings in it
[tasks addObject:@"Walk the dogs"]; [tasks addObject:@"Feed the hogs"]; [tasks addObject:@"Chop the logs"];
}
// Create and configure the UIWindow instance
CGRect windowFrame = [[UIScreen mainScreen] bounds];
UIWindow *theWindow = [[UIWindow alloc] initWithFrame:windowFrame]; [self setWindow:theWindow];
...
}
Figure 27.8 Complete object diagram for iTahDoodle
Build and run the application. The table view should display your test data. You still can’t add new tasks, though. Once more into the breach!
188