Stanford Cs193P: Developing Applications For Iphone 4, Ipod Touch, & Ipad Fall 2010
Stanford Cs193P: Developing Applications For Iphone 4, Ipod Touch, & Ipad Fall 2010
Developing Applications for iPhone 4, iPod Touch, & iPad Fall 2010
Today
Objective-C
Methods (Class and Instance) Instance Variables Properties Dynamic Binding Introspection nil and BOOL
Method Syntax
- (NSArray *)shipsAtPoint:(CGPoint)bombLocation withDamage:(BOOL)damaged;
Dash for instance method. Plus for class method. Will explain difference in a moment.
Method Syntax
- (NSArray *)shipsAtPoint:(CGPoint)bombLocation withDamage:(BOOL)damaged; Return type in parentheses
Method Syntax
- (NSArray *)shipsAtPoint:(CGPoint)bombLocation withDamage:(BOOL)damaged; First part of method name. Full name is shipsAtPoint:withDamage: Second part of method name.
Method Syntax
- (NSArray *)shipsAtPoint:(CGPoint)bombLocation withDamage:(BOOL)damaged; Type of rst argument in parentheses. Type of second argument in parentheses. This one happens to be a C struct. This one is a BOOL (boolean value).
Method Syntax
- (NSArray *)shipsAtPoint:(CGPoint)bombLocation withDamage:(BOOL)damaged; Name of rst argument. Use it like a local variable inside method denition. Name of second argument.
Method Syntax
- (NSArray *)shipsAtPoint:(CGPoint)bombLocation withDamage:(BOOL)damaged; Line up colons when there are lots of arguments (or argument names are long). - (void)splitViewController:(UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController; Use IBAction (same as void) to alert Interface Builder of an action. - (IBAction)digitPressed:(UIButton *)sender; - (IBAction)digitPressed:(id)sender; - (IBAction)digitPressed:sender; - (IBAction)digitPressed; / same as (id)sender version /
Stanford CS193p Fall 2010
Instance Methods
Starts with a dash
- (IBAction)digitPressed:(UIButton *)sender;
Normal methods you are used to Can access instance variables inside as if they were locals Can send messages to self and super inside
Both dispatch the message to the calling object, but use different implementations If a superclass of yours calls a method on self, it will your implementation (if one exists)
Class Methods
Starts with a plus. Used for allocation, singletons, utilities
+ (id)alloc; / makes space for an object of the receivers class (always pair w/init) / + (id)motherShip; / returns the one and only, shared (singleton) mother ship instance / + (int)turretsOnShipOfSize:(int)shipSize; / informational utility method /
Can not access instance variables inside Messages to self and super mean something a little different
Both invoke only other class methods. Inheritance does work.
Instance Variables
Scope
By default, instance variables are @protected (only the class and subclasses can access). Can be marked @private (only the class can access) or @public (anyone can access).
Scope syntax
@interface MyObject : NSObject { int foo; @private int eye; @protected int bar; @public int forum; int apology; @private int jet; }
Protected: foo & bar Private: eye & jet Public: forum & apology
Properties
Forget everything on the previous slide!
Mark all of your instance variables @private. Use @property and dot notation to access instance variables.
Now anyone can access your instance variable using dot notation
someObject.eye = newEyeValue; int eyeValue = someObject.eye; // set the instance variable // get the instance variables current value
Stanford CS193p Fall 2010
Properties
Forget everything on the previous slide!
Mark all of your instance variables @private. Use @property and dot notation to access instance variables.
Note the capitalization. Instance variables almost always start with lower case. In any case, the letter after set MUST be capitalized. Otherwise dot notation will not work.
Now anyone can access your instance variable using dot notation
someObject.eye = newEyeValue; int eyeValue = someObject.eye; // set the instance variable // get the instance variables current value
Stanford CS193p Fall 2010
Properties
@property
You can get the compiler to generate set/get method declarations with @property directive
@interface MyObject : NSObject { @private int eye; } @property int eye; - (int)eye; - (void)setEye:(int)anInt; @end
Properties
@property
You can get the compiler to generate set/get method declarations with @property directive
@interface MyObject : NSObject { @private int eye; } @property int eye; @end
Properties
@property
You can get the compiler to generate set/get method declarations with @property directive
@interface MyObject : NSObject { @private int eye; } @property int eye; @end
readonly
Properties
An @property does not have to match an instance variable name
For example ...
@interface MyObject : NSObject { @private int p_eye; } @property int eye; @end
Properties
But whatever you declare, you must then implement
For example, consider the following header (.h) le:
@interface MyObject : NSObject { @private int eye; } @property int eye; @end
Properties
Or consider the case where the variable name is different
Header (.h) le:
@interface MyObject : NSObject { @private int p_eye; } @property int eye; @end
Properties
Or how about the no corresponding variable case?
Header (.h) le:
@interface MyObject : NSObject { } @property (readonly) int eye; @end
Properties
Let the compiler help you with implementation using
Header (.h) le:
@interface MyObject : NSObject { @private int eye; } @property int eye; @end
@synthesize!
Properties
Let the compiler help you with implementation using
Header (.h) le:
@interface MyObject : NSObject { @private int eye; } @property int eye; @end
@synthesize!
Properties
Let the compiler help you with implementation using
Header (.h) le:
@interface MyObject : NSObject { @private int eye; } @property int eye; @end
@synthesize!
Properties
If you use @synthesize, you can still implement one or the other
@implementation MyObject @synthesize eye; - (void)setEye:(int)anInt { if (anInt > 0) eye = anInt; } @end
The method - (int)eye will still be implemented for you by @synthesize Your implementation of setEye: is the one that will count If you implemented both the setter and the getter, the @synthesize would be ignored
Properties
Its common to use dot notation to access ivars inside your class
Its not the same as referencing the instance variable directly. For example, if eye is an instance variable ...
int x = eye;
The latter calls the getter method (which is usually what you want for subclassability).
Properties
Why properties?
Most importantly, it provides safety and subclassability for instance variables. But the syntax also makes code look more consistent with C structs.
typedef struct { float x; float y; } Point;
Notice that we capitalize Point (just like a class name). It makes our C struct seem just like an object
@interface Bomb @property Point position; @end @interface Ship : Vehicle { float width, height; Point center; } @property float width; @property float height; @property Point center; - (BOOL)getsHitByBomb:(Bomb *)bomb; @end
Properties
Why properties?
Most importantly, it provides safety and subclassability for instance variables. But the syntax also makes code look more consistent with C structs.
typedef struct { float x; float y; } Point; @interface Bomb @property Point position; @end
Instance variables may or may not exist here. Remember that @property is just declaring the property. Bomb would still have to implement setter and getter (could use @synthesize, of course).
@interface Ship : Vehicle { float width, height; Point center; } @property float width; @property float height; @property Point center; - (BOOL)getsHitByBomb:(Bomb *)bomb; @end
Properties
Why properties?
Most importantly, it provides safety and subclassability for instance variables. But the syntax also makes code look more consistent with C structs.
typedef struct { float x; float y; } Point; @interface Bomb @property Point position; @end @interface Ship : Vehicle { float width, height; Point center; } @property float width; @property float height; @property Point center; - (BOOL)getsHitByBomb:(Bomb *)bomb; @end
Returns whether the passed bomb would hit the receiving Ship.
Stanford CS193p Fall 2010
Properties
Why properties?
Most importantly, it provides safety and subclassability for instance variables. Notice access to instance But the syntax also makes code look more consistent with C structs. variable using property of self @implementation Ship typedef struct { instead of directly. float x;
float y; } Point; @interface Bomb @property Point position; @end @interface Ship : Vehicle { float width, height; Point center; } @property float width; @property float height; @property Point center; - (BOOL)getsHitByBomb:(Bomb *)bomb; @end @synthesize width, height, center; - (BOOL)getsHitByBomb:(Bomb *)bomb { float leftEdge = self.center.x - self.width/2; float rightEdge = ...; return ((bomb.position.x (bomb.position.x (bomb.position.y (bomb.position.y } @end
Stanford CS193p Fall 2010
Properties
Why properties?
Most importantly, it provides safety and subclassability for instance variables. But the syntax also makes code look more consistent with C structs.
typedef struct { float x; float y; } Point; @interface Bomb @property Point position; @end @interface Ship : Vehicle { float width, height; Point center; } @property float width; @property float height; @property Point center; - (BOOL)getsHitByBomb:(Bomb *)bomb; @end @implementation Ship @synthesize width, height, center; - (BOOL)getsHitByBomb:(Bomb *)bomb { float leftEdge = self.center.x - self.width/2; float rightEdge = ...; return ((bomb.position.x (bomb.position.x (bomb.position.y (bomb.position.y } @end >= <= >= <= leftEdge) && rightEdge) && topEdge) && bottomEdge));
Properties
Why properties?
Most importantly, it provides safety and subclassability for instance variables. But the syntax also makes code look more consistent with C structs.
typedef struct { float x; float y; } Point; @interface Bomb @property Point position; @end @interface Ship : Vehicle { float width, height; Point center; } @property float width; @property float height; @property Point center; - (BOOL)getsHitByBomb:(Bomb *)bomb; @end @implementation Ship @synthesize width, height, center; - (BOOL)getsHitByBomb:(Bomb *)bomb { float leftEdge = self.center.x - self.width/2; float rightEdge = ...; return ((bomb.position.x (bomb.position.x (bomb.position.y (bomb.position.y } @end >= <= >= <= leftEdge) && rightEdge) && topEdge) && bottomEdge));
Private Properties
Do all @propertys have to be public?
Example (this is all in MyObjects .m le):
@interface MyObject() @property double myEyesOnly; @end @implementation MyObject @synthesize eye, myEyesOnly; @end
No. It is possible to declare a private interface to your class inside your implementation le.
This is the magic to declare your private stuff. You can put properties and methods here, but not more instance variables.
The property myEyesOnly can only be set/get via self.myEyesOnly since it is private.
Properties
Theres more to think about when a @property is an object
Well postpone that discussion to later on when we talk about memory management
Dynamic Binding
All objects are allocated in the heap, so you always use a pointer
Examples ...
NSString *s = ...; id obj = s;
/ static typed /
Object Typing
@interface Vehicle - (void)move; @end @interface Ship : Vehicle - (void)shoot; @end Ship *s = [[Ship alloc] init]; [s shoot]; [s move];
No compiler warning. Perfectly legal since s isa Vehicle. Normal object-oriented stuff here.
Object Typing
@interface Vehicle - (void)move; @end @interface Ship : Vehicle - (void)shoot; @end Ship *s = [[Ship alloc] init]; [s shoot]; [s move]; Vehicle *v = s;
Object Typing
@interface Vehicle - (void)move; @end @interface Ship : Vehicle - (void)shoot; @end Ship *s = [[Ship alloc] init]; [s shoot]; [s move]; Vehicle *v = s; [v shoot];
Compiler warning! Would not crash at runtime though. But only because we know v is a Ship. Compiler only knows v is a Vehicle.
Object Typing
@interface Vehicle - (void)move; @end @interface Ship : Vehicle - (void)shoot; @end Ship *s = [[Ship alloc] init]; [s shoot]; [s move]; Vehicle *v = s; [v shoot]; id obj = ...; [obj shoot];
No compiler warning. The compiler knows that the method shoot exists, so its not impossible that obj might respond to it. But we have not typed obj enough for the compiler to be sure its wrong. So no warning. Might crash at runtime if obj is not a Ship (or an object of some other class that implements a shoot method).
Object Typing
@interface Vehicle - (void)move; @end @interface Ship : Vehicle - (void)shoot; @end Ship *s = [[Ship alloc] init]; [s shoot]; [s move]; Vehicle *v = s; [v shoot]; id obj = ...; [obj shoot]; [obj someMethodNameThatNoObjectAnywhereRespondsTo];
Compiler warning! Compiler has never heard of this method. Therefore its pretty sure obj will not respond to it.
Object Typing
@interface Vehicle - (void)move; @end @interface Ship : Vehicle - (void)shoot; @end Ship *s = [[Ship alloc] init]; [s shoot]; [s move]; Vehicle *v = s; [v shoot]; id obj = ...; [obj shoot]; [obj someMethodNameThatNoObjectAnywhereRespondsTo]; NSString *hello = @hello; [hello shoot];
Compiler warning. The compiler knows that NSString objects do not respond to shoot. Guaranteed crash at runtime.
Stanford CS193p Fall 2010
Object Typing
@interface Vehicle - (void)move; @end @interface Ship : Vehicle - (void)shoot; @end Ship *s = [[Ship alloc] init]; [s shoot]; [s move]; Vehicle *v = s; [v shoot]; id obj = ...; [obj shoot]; [obj someMethodNameThatNoObjectAnywhereRespondsTo]; NSString *hello = @hello; [hello shoot]; Ship *helloShip = (Ship *)hello;
No compiler warning. We are casting here. The compiler thinks we know what were doing.
Object Typing
@interface Vehicle - (void)move; @end @interface Ship : Vehicle - (void)shoot; @end Ship *s = [[Ship alloc] init]; [s shoot]; [s move]; Vehicle *v = s; [v shoot]; id obj = ...; [obj shoot]; [obj someMethodNameThatNoObjectAnywhereRespondsTo]; NSString *hello = @hello; [hello shoot]; Ship *helloShip = (Ship *)hello; [helloShip shoot];
No compiler warning! Weve forced the compiler to think that the NSString is a Ship. Alls well, the compiler thinks.
Object Typing
@interface Vehicle - (void)move; @end @interface Ship : Vehicle - (void)shoot; @end Ship *s = [[Ship alloc] init]; [s shoot]; [s move]; Vehicle *v = s; [v shoot]; id obj = ...; [obj shoot]; [obj someMethodNameThatNoObjectAnywhereRespondsTo]; NSString *hello = @hello; [hello shoot]; Ship *helloShip = (Ship *)hello; [helloShip shoot]; [(id)hello shoot];
No compiler warning! Weve forced the compiler to ignore the object type by casting in line. Alls well, the compiler thinks. Guaranteed crash at runtime.
Stanford CS193p Fall 2010
Introspection
So when do we use id? Isnt it always bad?
No, we might have a collection (e.g. an array) of objects of different classes. But wed have to be sure we know which was which before we sent messages to them. How do we do that? Introspection.
Introspection
Method testing methods take a selector (SEL)
if ([obj respondsToSelector:@selector(shoot)]) { [obj shoot]; }
SEL
nil
The value of an object pointer that does not point to anything
id obj = nil; NSString *hello = nil;
NSObject
Thus, instance variables that are pointers to objects start out with the value of nil.
BOOL
Objective-Cs boolean type (actually just a typedef)
Can be tested implicitly if (flag) { } if (!flag) { } YES means true, NO means false NO == 0, YES is anything else if (flag == YES) { } if (flag == NO) { } if (flag != NO) { }
Foundation Framework
NSObject
Base class for pretty much every object in the iOS SDK Implements memory management primitives (more on this later) Implements introspection methods - (NSString *)description is a useful method to override (it %@ in NSLog()). s
Foundation Framework
NSString
International (any language) strings using Unicode. Used throughout iOS instead of C languages char * type. Compiler will create an NSString for you using @foo notation. An NSString instance can not be modied! They are immutable. Usual usage pattern is to send a message to an NSString and it will return you a new one.
[display setText:[[display text] stringByAppendingString:digit]];
/ same but with properties / display.text = [NSString stringWithFormat:@%g, brain.operand]; / class method / Tons of utility functions available (case conversion, URLs, substrings, type conversions, etc.).
display.text = [display.text stringByAppendingString:digit];
NSMutableString
Mutable version of NSString. Can do some of the things NSString can do without creating a new one (i.e. in-place changes).
NSMutableString *mutString = [[NSMutableString alloc] initWithString:@0.]; [mutString appendString:digit];
Stanford CS193p Fall 2010
Foundation Framework
NSNumber
Object wrapper around primitive types like int, float, double, BOOL, etc.
NSNumber *num = [NSNumber numberWithFloat:36.5]; float f = [num floatValue];
Useful when you want to put these primitive types in a collection (e.g. NSArray or NSDictionary).
NSValue
Generic object wrapper for other non-object data types.
CGPoint point = CGPointMake(25.0, 15.0); NSValue *val = [NSValue valueWithCGPoint:point];
NSData
Bag of bits. Used to save/restore/transmit data throughout the iOS SDK.
NSDate
Used to nd out the time right now or to store past or future times/dates. See also NSCalendar, NSDateFormatter, NSDateComponents.
Stanford CS193p Fall 2010
Foundation Framework
NSArray
Ordered collection of objects. Immutable. Thats right, you cannot add or remove objects to it once its created. Important methods:
+ (id)arrayWithObjects:(id)firstObject, ...; - (int)count; - (id)objectAtIndex:(int)index; - (void)makeObjectsPerformSelector:(SEL)aSelector; - (NSArray *)sortedArrayUsingSelector:(SEL)aSelector; - (id)lastObject;
NSMutableArray
Mutable version of NSArray.
- (void)addObject:(id)anObject; - (void)insertObject:(id)anObject atIndex:(int)index; - (void)removeObjectAtIndex:(int)index;
Stanford CS193p Fall 2010
Foundation Framework
NSDictionary
Hash table. Look up objects using a key to get a value. Immutable. Thats right, you cannot add or remove objects to it once its created. Keys are objects which must implement - (NSUInteger)hash & - (BOOL)isEqual:(NSObject *)obj Keys are usually NSString objects. Important methods:
- (int)count; - (id)objectForKey:(id)key; - (NSArray *)allKeys; - (NSArray *)allValues;
NSMutableDictionary
Mutable version of NSDictionary.
- (void)setObject:(id)anObject forKey:(id)key; - (void)removeObjectForKey:(id)key; - (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary;
Stanford CS193p Fall 2010
Foundation Framework
NSSet
Unordered collection of objects. Immutable. Thats right, you cannot add or remove objects to it once its created. Important methods:
- (int)count; - (BOOL)containsObject:(id)anObject; - (id)anyObject; - (void)makeObjectsPerformSelector:(SEL)aSelector; - (id)member:(id)anObject;
NSMutableSet
Mutable version of NSSet.
- (void)addObject:(id)anObject; - (void)removeObject:(id)anObject; - (void)unionSet:(NSSet *)otherSet; - (void)minusSet:(NSSet *)otherSet; - (void)intersectSet:(NSSet *)otherSet;
Stanford CS193p Fall 2010
Enumeration
Looping through members of a collection in an efcient manner
Language support using for-in (similar to Java) Example: NSArray of NSString objects
NSArray *myArray = ...; for (NSString *string in myArray) { } double value = [string doubleValue];
/ do something with obj, but make sure you dont send it a message it does not respond to /
if ([obj isKindOfClass:[NSString class]]) { } }
Enumeration
Looping through the keys or values of a dictionary
Example:
NSDictionary *myDictionary = ...; for (id key in myDictionary) {
Property List
The term Property List just means a collection of collections
Specically, it is any graph of objects containing only the following classes: NSArray, NSDictionary, NSNumber, NSString, NSDate, NSData
An NSDictionary is one only if all keys and values are too Why dene this term?
An NSArray of NSDictionarys whose keys are NSStrings and values are NSNumbers is one.
Because the SDK has a number of methods which operate on Property Lists. Usually to read them from somewhere or write them out to somewhere. [plist writeToFile:(NSString *)path atomically:(BOOL)]; // plist is NSArray or NSDictionary
Stanford CS193p Fall 2010
Next Time
More Foundation Object Allocation/Initialization Memory Management Demo