- •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
The block-based future
Can I change the variables that the block has copied?
By default, the variables captured by a block are constant within the block, and you cannot change their values. Object pointer variables, for example, are constant within the scope of the block. (Although you can still send the object messages that can change its contents, you cannot modify the pointer itself.)
Sometimes, however, you want to be able to modify an external variable within a block. To do this, you must declare the external variable using the __block keyword. For instance, in the following code, you increment the external variable counter.
__block int counter = 0;
void (^counterBlock)() = ^{ counter++; };
...
counterBlock(); // Increments counter to 1 counterBlock(); // Increments counter to 2
Without the __block keyword, you would get a compilation error in the block definition, indicating that the value of counter cannot be changed.
The block-based future
Blocks can be difficult to understand and to use. However, they are extremely useful and powerful in heavily event-driven applications common in Mac and iOS programming. Apple’s APIs are using blocks more and more. For instance, the ALAssetLibrary and GameKit frameworks use many blockbased methods. It’s a good idea to use Apple’s block-based methods whenever they are available to become more comfortable with blocks.
Challenges
Anonymous block
The example in this chapter puts the block declaration, assignment, and usage on three separate lines of code for readability.
When you need to pass an integer into a method, such as NSNumber’s numberWithInt:, you can pass the int anonymously:
//Option 1: Totally break it down int i;
i = 5;
NSNumber *num = [NSNumber numberWithInt:i];
//Option 2: Skip the variable declaration NSNumber *num = [NSNumber numberWithInt:5];
Because blocks are variables, you can do this with blocks as well. In fact, this is the most common way to use blocks. You will rarely declare a block variable so that you can pass the block into methods; you’ll usually use them anonymously.
Modify the exercise in this chapter to pass the block anonymously as an argument to enumerateObjectsUsingBlock:. That is, keep the block, but get rid of the block variable.
235
Chapter 32 Blocks
NSNotificationCenter
In Chapter 24, you used NSNotificationCenter’s addObserver:selector:name:object: method to register to receive callbacks via your zoneChange: method. Update that exercise to use the addObserverForName:object:queue:usingBlock: method instead. Look up its details in the developer documentation.
This method takes a block as an argument and then executes the block instead of calling back to your object when the specified notification is posted. This means that your zoneChange: method will never be called. The code inside this method will instead be in the block.
The passed-in block should take a single argument (an NSNotification *) and return nothing, just as the zoneChange: method does.
You can pass nil as the argument for queue:; this argument is used for concurrency, a topic we won’t cover in this book.
236
Part VI
Advanced C
To be a competent Objective-C programmer, you must also be a competent C programmer. There are a few more things that you should really know about C. These topics are not ideas that you will use everyday, but you will encounter them occasionally, so I wanted to introduce you to them here.
This page intentionally left blank
33
Bitwise Operations
In the first part of this book, I described the memory of a computer as a vast meadow of switches (billions of switches) that could be turned on or off. Each switch represents one bit, and we usually use 1 to mean “on” and 0 to mean “off.”
However, you never address a single bit. Instead, you deal with byte-sized chunks of bits. If you think of a byte as an unsigned 8-bit integer, each bit represents another power of two:
Figure 33.1 One byte representing the decimal number 60
As a side-effect of living with 10 fingers, people like to work with decimal numbers (base-10). Computers, however, like powers of 2. Programmers often use a base-16 number system (16 = 24) known as hexadecimal or just “hex.” This is especially true when we are dealing with individual bits of an integer.
We use the letters a, b, c, d, e, and f for the extra digits. Thus, counting in hex goes like this: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, 10, 11, …
To make it clear when we are writing in hex, we prefix the number with 0x. Here is the same number and byte expressed using hex:
Figure 33.2 One byte representing the hex number 0x3c
Note that one byte can always be described as a two-digit hex number (like 3c). This makes hex a reasonable way to look at binary data. A tough-guy programmer thing to say is “I reversed engineered the file format by studying the document files in a hex editor.” Want to see a file as a list of hexencoded bytes? In Terminal, run hexdump on the file:
239