- •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 33 Bitwise Operations
unsigned char d = a & b;
printf("Hex: %x & %x = %x\n", a, b, d); printf("Decimal: %d & %d = %d\n", a, b, d);
return 0;
}
When you run it, you will see the two bytes bitwise-ANDed together:
Hex: 3c & a9 = 28
Decimal: 60 & 169 = 40
In Objective-C, we use bitwise-AND to see if a certain bit, or flag, is on. For example, if you were handed an instance of NSDataDetector, you could check if it was set to look for phone numbers like this:
if ([currentDetector checkingTypes] & NSTextCheckingTypePhoneNumber) { NSLog(@"This one is looking for phone numbers");
}
The checkingTypes method returns an integer that is the bitwise-OR result of all the flags this instance of NSDataDetector has on. You bitwise-AND this integer with a particular NSTextCheckingType constant and check the result. If the bit that is on in NSTextCheckingTypePhoneNumber is not on in the data detector’s setting, then the result of bitwise-ANDing them will be all zeroes. Otherwise, you’ll get a non-zero result, and you’ll know that this data detector does look for phone numbers.
Note that when we use bits this way, we don’t care what the integers in these cases equate to numerically. We use the bit placement within the integer to represent something other than a certain power of 2.
Other bitwise operators
For completeness, here are the other bitwise operators. These are less commonly used in Objective-C but good to know.
Exclusive OR
You can exclusive-or (XOR) two bytes together to create a third. A bit in the third byte is 1 if exactly one of the corresponding bits in the input bytes is 1.
Figure 33.5 Two bytes bitwise-XORed together
242
Complement
This is done with the ^ operator. Add to main.c:
unsigned char e = a ^ b;
printf("Hex: %x ^ %x = %x\n", a, b, e); printf("Decimal: %d ^ %d = %d\n", a, b, e);
return 0;
}
When you run it you will see:
Hex: 3c ^ a9 = 95
Decimal: 60 ^ 169 = 149
This operator sometimes causes beginners some confusion. In most spreadsheet programs, the ^ operator is exponentiation: 2^3 means 23. In C, we use the pow() function for exponentiation:
double r = pow(2.0, 3.0); // Calculate 2 raised to the third power
Complement
If you have a byte, the complement is the byte that is the exact opposite: each 0 becomes a 1 and each 0 becomes a 1.
Figure 33.6 The complement
This is done with the ~ operator. Add a few lines to main.c:
unsigned char f = ~b;
printf("Hex: The complement of %x is %x\n", b, f); printf("Decimal: The complement of %d is %d\n", b, f);
return 0;
}
You should see:
Hex: The complement of a9 is 56
Decimal: The complement of 169 is 86
Left-shift
If you left-shift the bits, you take each bit and move it toward the most significant bit. The ones that are on the left side of the number are forgotten, and the holes created on the right are filled with zeros.
243
Chapter 33 Bitwise Operations
Figure 33.7 Left-shifting by 2
Left-shift is done with the << operator. Add a shift of two places to main.c:
unsigned char g = a << 2;
printf("Hex: %x shifted left two places is %x\n", a, g); printf("Decimal: %d shifted left two places is %d\n", a, g);
return 0;
}
When this code runs, you will see:
Hex: 3c shifted left two places is f0
Decimal: 60 shifted left two places is 240
Every time you left-shift a number one place, you double its value.
Right-shift
The right-shift operator should not be much of a surprise. Add code to main.m:
unsigned char h = a >> 1;
printf("Hex: %x shifted right one place is %x\n", a, h); printf("Decimal: %d shifted right one place is %d\n", a, h);
return 0;
}
When run:
Hex: 3c shifted right one places is 1e
Decimal: 60 shifted right two places is 30
Figure 33.8 Right-shifting by 1
244