Skip to main content

Xcode and iOS programming

A digest of reading book 'iOS Programming - Big  Nerd Ranch'

#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
single place.

#Core Foundation
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

#Toll-Free Bridging
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
bridging.
e.g.
// Create an NSString
NSString *nsString = @"Toll-Free";
// Cast nsString to a CFString and get its length with a CF function
CFStringRef cfString;
cfString = (CFStringRef) nsString; // Cast it to a CFString

NSString *nsString2;
nsString2 = (NSString*) cfString;


#File's Owner
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.


#First Responder
This object doesn't have much use in iOS right now; it is a relic from Desktop Cocoa. You can
ignore it.

#The Heap
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.

#The Stack
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.

#Object  Ownership
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
memory leak.
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.

#Compiling
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.

#Linking
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.


#MapView Delegate
e.g.
@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
didUpdateUserLocation:(MKUserLocation *)userLocation
{
// Here we are... but how do we actually zoom?
CLLocationCoordinate2D loc = [userLocation coordinate];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, 250, 250);
[worldView setRegion:region animated:YES];
}

#UIDatePicker
self.datePicker.minimumDate = [NSDate dateWithTimeIntervalSinceNow:60];
will confirm that the date picker will only allow the user to select a date in the future.

#UIView
loadView: is overridden to create a view controller’s view programmatically.
e.g.
- (void)loadView
{
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;
[backgroundView addSubview:textField];
self.view = backgroundView;
}

To present a view controller modally, you send presentViewController:animated:completion: to
the UIViewController whose view is on the screen


#UIResponder
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.

#UINavigationController

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.
e.g.
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
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];
}

#UIViewController
[self presentViewController: navController animated:YES completion:nil];
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];



#NSKeyedArchiver and NSKeyedUnarchiver
- (BOOL)saveChanges
{
NSString *path = [self itemArchivePath];
// Returns YES on success
return [NSKeyedArchiver archiveRootObject:self.privateItems
toFile:path];
}

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.

#NSBundle

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.
e.g.
// 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"

#UITableViewCell
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.
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:@"UITableViewCell"];
}

so, in the cellForRowAtIndexPath, you don't have to check the null of dequeueReusableCell any more.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:@"UITableViewCell" forIndexPath:indexPath];












Comments

Popular posts from this blog

Quicksort implementation by using Java

 source: http://www.algolist.net/Algorithms/Sorting/Quicksort. The divide-and-conquer strategy is used in quicksort. Below the recursion step is described: 1st: Choose a pivot value. We take the value of the middle element as pivot value, but it can be any value(e.g. some people would like to pick the first element and do the exchange in the end) 2nd: Partition. Rearrange elements in such a way, that all elements which are lesser than the pivot go to the left part of the array and all elements greater than the pivot, go to the right part of the array. Values equal to the pivot can stay in any part of the array. Apply quicksort algorithm recursively to the left and the right parts - the previous pivot element excluded! Partition algorithm in detail: There are two indices i and j and at the very beginning of the partition algorithm i points to the first element in the array and j points to the last one. Then algorithm moves i forward, until an element with value greater or equal

Live - solving the jasper report out of memory and high cpu usage problems

I still can not find the solution. So I summary all the things and tell my boss about it. If any one knows the solution, please let me know. Symptom: 1.        The JVM became Out of memory when creating big consumption report 2.        Those JRTemplateElement-instances is still there occupied even if I logged out the system Reason:         1. There is a large number of JRTemplateElement-instances cached in the memory 2.     The clearobjects() method in ReportThread class has not been triggered when logging out Action I tried:      About the Virtualizer: 1.     Replacing the JRSwapFileVirtualizer with JRFileVirtualizer 2.     Not use any FileVirtualizer for cache the report in the hard disk Result: The japserreport still creating the a large number of JRTemplateElement-instances in the memory        About the work around below,      I tried: item 3(in below work around list) – result: it helps to reduce  the size of the JRTemplateElement Object        

Stretch a row if data overflows in jasper reports

It is very common that some columns of the report need to stretch to show all the content in that column. But  if you just specify the property " stretch with overflow' to that column(we called text field in jasper report world) , it will just stretch that column and won't change other columns, so the row could be ridiculous. Haven't find the solution from internet yet. So I just review the properties in iReport one by one and find two useful properties(the bold  highlighted in example below) which resolve the problems.   example: <band height="20" splitType="Stretch" > <textField isStretchWithOverflow="true" pattern="" isBlankWhenNull="true"> <reportElement stretchType="RelativeToTallestObject" mode="Opaque" x="192" y="0" width="183" height="20"/> <box leftPadding="2"> <pen lineWidth="0.25"/>