- •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 28 Your First Cocoa Application
So when do you use Interface Builder and when do you set up views programmatically? Under simple circumstances, either will work. We could have built iTahDoodle’s interface with a XIB. In general, however, the more complex your user interface, the more sense it makes to use Interface Builder.
(Now that you’ve seen more of Xcode, take a look at the tear-out card at the back of this book. This card contains keyboard shortcuts for navigating around Xcode. There are a bunch of them! As you continue with Xcode, use this card to find shortcuts that will save you time and clicks.)
Making connections
Creating and configuring views is not all that you can do in Interface Builder. You can also connect, or “wire,” these view objects to your application’s code. In particular, you can set target-action pairs and assign pointers.
To the left of the layout grid is a list of “placeholders” and objects. This is called the document outline. (If you just see a stack of icons without labels, click the button to reveal the expanded list.)
Figure 28.10 Minimized and expanded document outline
Find File's Owner under the Placeholders section of the document outline. A placeholder stands in for a particular object that cannot be specified until runtime. File's Owner stands in for whichever object will load this XIB as its user interface. In your case, File's Owner represents an instance of BNRDocument.
Now select the Insert button in the editor and Control-drag to File's Owner.
198
Making connections
Figure 28.11 Making connections
When you release the mouse button, a small pop-up will appear showing the available connections that you can make. Choose createNewItem: as the action to be triggered by the button.
Figure 28.12 Selecting an action
199
Chapter 28 Your First Cocoa Application
You’ve now configured the target-action pair. This is equivalent to the following code in iTahDoodle.
[insertButton addTarget:self action:@selector(addTask:)
forControlEvents:UIControlEventTouchUpInside];
Next, connect BNRDocument’s itemTableView outlet. Control-drag from File's Owner (standing in for the BNRDocument) to the NSTableView and release. Choose the only option that appears for this outlet:
itemTableView.
Figure 28.13 Making more connections
Finally, Control-Shift-click on the table view and select the NSTableView from the list. Then Controldrag from the table view to File's Owner and select dataSource from the connection pop-up.
200
Making connections
Figure 28.14 Connecting the table view’s data source
So what, exactly, did you just do? You assigned pointers. Your BNRDocument class declares a pointer to an NSTableView. You instructed Interface Builder that you want this pointer to point to the specific NSTableView instance that you dragged onto the window. Similarly, the table view has a few pointers of its own, like dataSource. You instructed Interface Builder to point the table view’s dataSource pointer at your BNRDocument. This is equivalent to when you set the table view’s data source programmatically in iTahDoodle.
[taskTable setDataSource:self];
When you entered the IBOutlet and IBAction keywords, you were flagging those outlets and actions for Interface Builder, saying “Hey! When I try to connect a pointer in IB, make sure and put this item in the list of available connections!” As you write your code, Interface Builder scans for IBOutlet and IBAction keywords so that it knows what connections you might want to make.
Here are the actual definitions:
#define IBAction void #define IBOutlet
From what we learned about #define, we know that IBAction is replaced with void before the compiler sees it and that IBOutlet disappears altogether. Thus, at compile time, all IBOutlet keywords are removed entirely (leaving behind the outlets themselves). IBAction keywords are replaced by void because actions invoked by user interface controls are not expected to have a return value.
Note that you don’t allocate XIB-based user interface elements as you do when creating your interface programmatically. They are automatically allocated when the XIB is loaded at runtime.
Finally, recall that there is no pointer to the button. This is because an object only needs instance variables for objects it needs to send messages to. The button needs to send messages to the
201