#What Is a Framework?
A framework is a type of bundle—a directory hierarchy with a specified layout that
groups shared dynamic libraries, header files, and resources (images, sounds, nib files) in a
Core Foundation is a low-level C language framework that (partially) parallels the
Objective-C Foundation framework. It defines data types and provides services that are
used by many of the other C language frameworks
Some Foundation classes have a memory layout that is almost identical to the memory
layout of the corresponding Core Foundation class. For these classes, a pointer to the
Foundation object can be used as a reference to the corresponding Core Foundation
object and vice versa. All you need is the appropriate cast. Apple calls this feature toll-free
// Create an NSString
NSString *nsString = @"Toll-Free";
// Cast nsString to a CFString and get its length with a CF function
cfString = (CFStringRef) nsString; // Cast it to a CFString
nsString2 = (NSString*) cfString;
This is the object that will have access to the objects archived in the XIB file. It will be an
instance of UIViewController, which is the object responsible for managing events that
occur on this interface.
This object doesn't have much use in iOS right now; it is a relic from Desktop Cocoa. You can
All Objective-C objects are stored in a part of memory called the heap. When we send an alloc message to a class, a chunk of memory is allocated from the heap. This chunk includes space for the object's instance variables.
There is another part of memory called the stack that is separate from the heap. The reason for the names heap and stack has to do with how we visualize them. The heap is a giant heaping mess of objects, and we use pointers to remember where those objects are stored within the help. The stack, on the other hand, can be visualized as a physical stack of frames.
When a method(or function) is executed, it allocates a chunk of memory from the stack. This chunk of memory is called a frame, and it stores the values from variables declared inside the method. A variable declared inside a method is called a local variable.
When an application launches and runs the main function, the frame for main is put at the bottom of the stack. When main calls another method, the frame for that method is added to the top of the stack. Of course, that method could call another method, and so on, until we have a towering stack of frames. Then, as each method or function finishes, its frame is popped off the stack and destroyed. If the method is called again, a brand new frame will be allocated and push on the stack.
Pointer variables convey ownership of the objects that they point to.
When a method has a local variable that points to an object, that method is said to own the object being pointed to; When an object has an instance variable that points to another object, the object with the pointer is said to own the object being pointed to.
The idea of object ownership helps us determine whether an object should be destroyed.
An object with no owners should be destroyed. An ownerless object cannot be sent messages and is
isolated and useless to the application. Keeping it around wastes precious memory. This is called a
An object with at least one owner must not be destroyed. If an object is destroyed but another
object or method still has a pointer to it (or, more accurately, a pointer to where it used to live), then
you have a very dangerous situation: sending a message to an object that no longer exists will crash
your application. This is called premature deallocation.
So how does an object lose an owner?
A variable that points to the object is changed to point to another object.
A variable that points to the object is set to nil.
A variable that points to the object is itself destroyed.
Once the preprocessor has finished, the generated intermediate files are compiled. Compiling an
intermediate file takes the Objective-C code and turns it into machine code. This machine code is stored in an object file, one for each intermediate file.
The compiling phase – the transition to machine code – is where we see most of our errors as
programmers. When the compiler doesn’t understand our code, it generates an error. We call errors generated during this phase compile-time errors or syntax errors.
An object file contains the machine code for the methods implemented in the implementation file.
However, within an implementation file, you use code from other implementation files. For example, WhereamiViewController.m uses the startUpdatingLocation method, and the machine code for that method is in the object file generated from CLLocationManager.m.
Instead of copying the code for this method into the object file for WhereamiViewController.m, the
compiler leaves a link to the object file for CLLocationManager.m. The Link Binary With Libraries phase is where these links are resolved. For short, we just call it the linking phase.
@interface WhereamiViewController : UIViewController <CLLocationManagerDelegate, MKMapViewDelegate>
The map view will send messages to its delegate when interesting events happen. Perhaps there is a message in the MKMapViewDelegate protocol for when the map view finds the user's location. Finding the location is an interesting event, and it would be the perfect time to "do the zoom".
- (void)mapView:(MKMapView *)mapView
// Here we are... but how do we actually zoom?
CLLocationCoordinate2D loc = [userLocation coordinate];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, 250, 250);
[worldView setRegion:region animated:YES];
self.datePicker.minimumDate = [NSDate dateWithTimeIntervalSinceNow:60];
will confirm that the date picker will only allow the user to select a date in the future.
loadView: is overridden to create a view controller’s view programmatically.
CGRect frame = [UIScreen mainScreen].bounds;
CustomeView *backgroundView = [[CustomeView alloc] initWithFrame:frame];
CGRect textFieldRect = CGRectMake(40, 70, 240, 30);
UITextField *textField = [[UITextField alloc] initWithFrame:textFieldRect];
// Setting the border style on the text field will allow us to see it more easily
textField.borderStyle = UITextBorderStyleRoundedRect;
self.view = backgroundView;
To present a view controller modally, you send presentViewController:animated:completion: to
the UIViewController whose view is on the screen
UIResponder is an abstract class in the UIKit framework. UIResponder defines methods for handling (or “responding to”) events: touch events, motion events (like a shake), and remote control events (like pausing or playing). Subclasses override these methods to customize how they respond to events. With touch events, it is obvious which view the user has touched. Touch events are sent directly to that view.
When using a UINavigationController, you cannot simply store all of the possible view
controllers in its stack. The viewControllers array of a navigation controller is dynamic – you start
with a root view controller and push view controllers depending on user input.
- (void)tableView:(UITableView *)tableView
CustomeController *detailViewController = [[CustomeController alloc] init];
NSArray *items = [[ItemStore sharedStore] allItems];
ItemStore *selectedItem = items[indexPath.row];
// Give detail view controller a pointer to the item object in row
detailViewController.item = selectedItem;
[self.navigationController pushViewController:detailViewController animated:YES];
[self presentViewController: navController animated:YES completion:nil];
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
#NSKeyedArchiver and NSKeyedUnarchiver
NSString *path = [self itemArchivePath];
// Returns YES on success
return [NSKeyedArchiver archiveRootObject:self.privateItems
restore the item:
NSString *path = [self itemArchivePath];
_privateItems = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
#Model-View-Controller-Store Design Pattern
The standard Model-View-Controller design pattern calls for the controller to be bear the burden
of saving and loading model objects. However, in practice, this can become overwhelming – the
controller is simply too busy handling the interactions between model and view objects to deal with the details of how objects are fetched and saved. Therefore, it is useful to move the logic that deals with where model objects come from and where they are saved to into another type of object: a store.
A store exposes a number of methods that allow a controller object to fetch and save model objects.One benefit of this approach, besides simplified controller classes, is that you can swap out how the store works without modifying the controller or the rest of your application. This can be a simple change, like the directory structure of the data, or a much larger change, like the format of the data. Thus, if an application has more than one controller object that needs to save and load data, you only have to change the store object.
When you build an iOS application project in Xcode, you create an application bundle. The application bundle contains the application executable and any resources you have bundled with your application. Resources are things like XIB files, images, audio files – any files that will be used at runtime. When you add a resource file to a project, Xcode is smart enough to realize that it should be bundled with your application.
// Get a pointer to the application bundle
NSBundle *applicationBundle = [NSBundle mainBundle];
// Ask for the path to a resource named myImage.png in the bundle
NSString *path = [applicationBundle pathForResource:@"myImage"
You registered a class with the table view to inform it which class should be instantiated
whenever it needs a new table view cell. Now that you are using a custom NIB file to load a
UITableViewCell subclass, you will register that NIB instead.
[self.tableView registerClass:[UITableViewCell class]
so, in the cellForRowAtIndexPath, you don't have to check the null of dequeueReusableCell any more.
- (UITableViewCell *)tableView:(UITableView *)tableView
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:@"UITableViewCell" forIndexPath:indexPath];