Category Archives: iPhone Programming
Standard Weight Calculator
icons
HelloPolygon
Application Lifecycle
User touches icon on home screen |
System calls main() |
main() calls UIApplicationMain() |
UIApplicationMain() creates instance of UIApplication |
UIApplication instance loads main Nib file, sets up based on application properties |
UIApplication instance goes into run loop, waiting for and forwarding events to interface elements (instances of UIResponder) |
User taps home button or does another termination activity |
UIApplication instance tells your delegate that the application is terminating |
UIApplicationMain() exits, main() exits, process exits |
View-based Application
main.m
-Basically just the C entry point function int main(int argc, char *argv[])
-Creates an autorelease pool
-Calls UIApplicationMain which creates a UIApplication object and starts the run loop
MainWindow.xib
-Contains a UIWindow (top of the view hierarchy) for things to be installed in
-Can be (usually is) customizable per platform
-Contains the Appliation Delegate (just an NSObject which its class set to YourAppDelegate)
-Application Delegate also has a couple of outlets wired up (notably to YourAppViewController)
YourApp-Info.plist
-A variety of application configuration properties
YourAppViewController.m & .h & .xib
-Has an instance variable for the UIWindow in MainWindow.xib called window
-Has an instance variable for YourAppViewController called viewController
-Has stubs for a lot of applicationDidxxx and applicationWillxxxx
-Most importantly application:didFinishLaunchingWithOptions:
This is the method where YourAppViewController’s view is added to the UIWindow
Also where the UIWindow is made visible [window makeKeyAndVisible]
lecture4
NSCopying Protocol
– (id) copyWithZone: (NSZone *) zone;
@end
If you adopt NSCopying, your object knows how to make copies of itself:
@interface Vehicle: NSObject<NSCopying>
{
NSColor* color;
}
// methods…
@end
Vehicle * vehicleCopy = [[[self class] allocWithZone: zone] initWithColor: color];
return vehicleCopy;
}
@interface Car: Vehicle // Car includes the <NSCopying> protocol
{
float drivingForce;
}
// methods…
@end
// Make sure Car’s drivingForce instance variable is copied.
-(id) copyWithZone: (NSZone *)zone {
Car * vehicleCopy = [super copyWithZone: zone];
[vehicleCopy setDrivingForce: drivingForce];
return vehicleCopy;
}
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/
Protocols/NSCopying_Protocol/Reference/Reference.html
Convenience constructor
NSNumber* zero_a = [[NSNumber alloc] initWithFloat:0.0f];
…
[zero_a release];
…
NSNumber* zero_b = [NSNumber numberWithFloat:0.0f];
…
//no need of release
@interface Vehicle : NSObject
{
NSColor* color;
}
-(void) setColor:(NSColor*)color;
+(id) vehicleWithColor:(NSColor*)color; //convenience constructor
@end
+(Vehicle*) vehicleWithColor:(NSColor*)color
{
//the value of “self” should not change here
self = [[self alloc] init]; // ERROR !
[self setColor:color];
return [self autorelease];
}
//Almost perfect constructor
+(id) vehicleWithColor:(NSColor*)color
{
id newInstance = [[Vehicle alloc] init]; // OK, but ignores potential sub-classes
[newInstance setColor:color];
return [newInstance autorelease];
}
+(id) vehicleWithColor:(NSColor*)color
{
id newInstance = [[[self class] alloc] init]; // PERFECT, the class is
// dynamically identified
[newInstance setColor:color];
return [newInstance autorelease];
}
@end
@end
…
//produces a (red) car
id car = [Car vehicleWithColor:[NSColor redColor]];
Autorelease
In C++
{
Point2D result(0.0f, 0.0f);
result.v[0] = v[0] + other.v[0];
result.v[1] = v[1] + other.v[1];
return result;
} //ERROR – it results in a dangling reference because the local object is destructed prior to the return of the function
Point2D& Point2D::operator+(const Point2D & other)
{
Point2D * result = new Point2D();
result.v[0] = v[0] + other.v[0];
result.v[1] = v[1] + other.v[1];
return result;
} //ERROR – it results in memory leakage because nobody will delete the created object
{
Point2D result(0.0f, 0.0f);
result.v[0] = v[0] + other.v[0];
result.v[1] = v[1] + other.v[1];
return result;
} // CORRECT – it returns a local class object by value
Point2D& Point2D::operator+= (const Point2D &other)
{
v[0] += other.v[0];
v[1] += other.v[1];
return *this;
} // CORRECT – it returns a self by reference
In Objective-C
{
Point2D* result = [[Point2D alloc] initWithX:([p1 getX] + [p2 getX])
andY:([p1 getY] + [p2 getY])];
return result;
}
//ERROR : the function performs “alloc”, so, it is creating
//an object with a reference counter of 1. According
//to the rule, it should destroy the object.
//This can lead to a memory leak when summing three points :
[calculator add:[calculator add:p1 and:p2] and:p3];
//The result of the first addition is anonymous
//and nobody can release it. It is a memory leak.
{
return [[Point2D alloc] initWithX:([p1 getX] + [p2 getX])
andY:([p1 getY] + [p2 getY])];
}
//ERROR : This is exactly the same code as above. The fact that
//no intermediate variable is used does not change anything.
{
Point2D* result = [[Point2D alloc] initWithX:([p1 getX] + [p2 getX])
andY:([p1 getY] + [p2 getY])];
[result release];
return result;
}
//ERROR : obviously, it is nonsense to destroy the object after creating it
{
Point2D* result = [[Point2D alloc] initWithX:([p1 getX] + [p2 getX])
andY:([p1 getY] + [p2 getY])];
[result autorelease];
return result; //a shorter writing is “return [result autorelease]”
}
//CORRECT : “result” will be automatically released later,
//after being used in the calling code