Upload
dinhkhue
View
214
Download
1
Embed Size (px)
Citation preview
• Not■ Active Pharmaceutical Ingredient■ Armor-Piercing Incendiary■ American Pirate Industries■ American Pain Institute
• But■ Application Programming Interface
3
• APIs allow your code to interface with the system• Well-designed APIs:
■ Make you more productive ■ Allow you to leverage existing code■ Let you write code that works as the user expects
• APIs live for a long time• API design is UI design for developers
4
Why is it important?
• Eliminates need to refer to documentation for every single API• Allows different subsystems to plug-in to each other more easily• Improves performance
8
Classes
• Use prefixes■ Protects against collisions■ Differentiate functional areas
NSStringUIViewCLLocation
9
Methods
• Focus on readability
• Use camel case• Choose clarity over brevity• Name all the arguments
- subviews- isEditable- insertObject:atIndex:
if (myTextField.isEditable) ...
10
- (id)initWithBitmapDataPlanes:(unsigned char **)p pixelsWide:(NSInteger)width pixelsHigh:(NSInteger)height bitsPerSample:(NSInteger)bps samplesPerPixel:(NSInteger)spp hasAlpha:(BOOL)alpha isPlanar:(BOOL)isPlanar colorSpaceName:(NSString *)space bitmapFormat:(NSBitmapFormat)format bytesPerRow:(NSInteger)rBytes bitsPerPixel:(NSInteger)pBits;
12
- (id)initWithBitmapDataPlanes:(unsigned char **)p :(NSInteger)width :(NSInteger)height :(NSInteger)bps :(NSInteger)spp :(BOOL)alpha :(BOOL)isPlanar :(NSString *)space :(NSBitmapFormat)format :(NSInteger)rBytes :(NSInteger)pBits;
13
id image = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:planes pixelsWide:32 pixelsHigh:32 bitsPerSample:32 samplesPerPixel:4 hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace bitmapFormat:NSAlphaFirstBitmapFormat bytesPerRow:0 bitsPerPixel:0];
14
Java version, circa 2000
NSBitmapImageRep image = new NSBitmapImageRep( planes, 32, 32, 32, 4, true, false, NSDeviceRGBColorSpace, NSAlphaFirstBitmapFormat, 0, 0);
15
• For boolean properties that are adjectives, use “is” on the getter• Do not embellish the getter with “get” or other verbs
- color - setColor:- isEditable - setEditable: - drawsBackground - setDrawsBackground:
- (UIColor *)getColor;- (NSString *)computeFullName;- (CGImageRef)computeThumbnailImage;
16
Acceptable use of “get”
• Use “get” on accessors that return values by reference
• Callers pass NULL in for the arguments they don’t want
- (void)getLineDash:(CGFloat *)pattern count:(NSInteger *)count phase:(CGFloat *)phase;
- (void)getBytes:(void *)buffer range:(NSRange)range;
17
Using @property
@property (copy) UIColor *color;@property (getter=isEditable) BOOL editable;@property BOOL drawsBackground;
18
• Framework prefix, followed by the type or functionality area ■ “CF” + “Range” + “Make”■ “CG” + “Path” + “Add Lines”
• The common prefix allows easier searching and sorting
CFRangeMake()NSRectFill()CGPathAddLines()
19
• Similar to functions• We also use some common suffixes
■ …Notification■ …Key
UITouchPhaseBegan NSTextCheckingCityKey UIKeyboardWillHideNotification
20
Naming conventions have evolved over time
CFRangeMake()UIRectFrame()NSRectFill()
NSMakeRange()NSFrameRect()NSHeight()
21
Be consistent
• Acceptable abbreviations
• Commonly used acronyms are fine
alloc, allocWithZone:, deallocintmax, min
PDFUSBASCIIURLXML
23
“Block” can be ambiguous
• Use only in the generic cases
• Alternatives
- indexOfObjectsPassingTest:
- sortedArrayUsingComparator:
+ addLocalMonitorForEventsMatchingMask:handler:
- recycleURLs:completionHandler:
- beginBackgroundTaskWithExpirationHandler:
- enumerateObjectsUsingBlock:
26
Memory management
• Object ownership is not transferred across calls• Except return values from methods
■ Whose names begin with■ alloc■ new■ copy, mutableCopy
■ retain
• You should never have to ask the question “Do I have to release the result from calling … ?”
27
Marking memory management mistakes in APIs
• Use this for static analysis purposes, not to define or justify bad APIs
NS_RETURNS_RETAINED
- (NSString *)fullName NS_RETURNS_RETAINED;
28
• Consistency• Performance
■ Impedance matching■ Mutability■ Concurrency
• Safety• Reusability• Convenience
30
Small number of basic data types in APIs
• Improves consistency• Allows code to fit together more easily• Eliminates need to do conversions
32
Small number of basic data types in APIs
• NSString• NSDate• NSURL• NSArray, NSDictionary• UIColor/NSColor• UIFont/NSFont• UIImage/NSImage• …
33
Not all basic data types are objects
• Use C types for numeric values■ NSInteger, NSUInteger■ CGFloat■ NSNumber only to wrap these where necessary
• For widely used types where abstraction is not important, structs OK ■ CGPoint/NSPoint■ CFRange/NSRange■ …
34
Multiple types for the same concept
• What’s up with…■ CGPoint and NSPoint?
■ Equivalent typedefs■ NSInteger, NSUInteger?
■ Enable moving to 64-bit■ CFStringRef and NSString?
■ “Toll-free” bridged
35
Mutable means changeable
• Many objects are by nature only mutable■ NSWindow■ UIScrollView
• Others, usually “value” objects, can exist in immutable forms■ NSString■ UIColor
• In some cases both make sense
36
NSString versus NSMutableString
• NSString
• NSMutableString
NSString *str = ...;NSString *result = [str stringByAppendingString:@“!”];
NSMutableString *str = ...;[str appendString:@“!”];
37
Why have immutable variants at all?
• Performance• Simpler implementation• Thread safety• Easier analysis of program logic
38
Which one to use in APIs?
• Immutable
• Mutable
• Immutable version is almost always the right one to use• Using @property:
- (NSString *)title;
- (NSMutableString *)title;
@property (copy) NSString *title;
39
Very few exceptions
• NSAttributedString
• NSMutableAttributedString
- (NSString *)string;
- (NSMutableString *)mutableString;
40
Achieve higher performance on multi-core machines
• Blocks are a good fit for representing concurrent work■ They can be processed by GCD or NSOperationQueue■ They can capture state
• Not all block usage is necessarily concurrent
41
Often there is an explicit option for concurrency
• Enumeration, sorting, and searching in collections
- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block;
[myArray enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id obj, NSUInteger i, BOOL *stop) { // ... process obj ... }];
What’s New in Foundation for iOS 4 Pacific HeightsTuesday 10:15AM
42
Often there is an explicit option for concurrency
• Receiving NSNotifications
• Non-nil queue argument enables concurrent posting to observer
- (id)addObserverForName:(NSString *)name object:(id)object queue:(NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *))block;
43
Often there is an explicit option for concurrency
• Synchronous and asynchronous checking in NSSpellChecker
- (NSArray *)checkString:(NSString *)stringToCheck range:(NSRange)range types:(NSTextCheckingTypes)types options:(NSDictionary *)opts inSpellDocumentWithTag:(NSInteger)tag orthography:(NSOrthography **)orthography wordCount:(NSInteger *)wordCount;
- (NSInteger)requestCheckingOfString:(NSString *)stringToCheck range:(NSRange)range types:(NSTextCheckingTypes)types options:(NSDictionary *)opts inSpellDocumentWithTag:(NSInteger)tag completionHandler:(void (^)(NSInteger sequenceNumber, NSArray *results, NSOrthography *orthography, NSInteger wordCount))handler;
44
• Consistency• Performance• Safety
■ Runtime errors■ Programming errors■ Atomicity
• Reusability• Convenience
46
Why is it important?
• Reduces chance of crashes• Allows easier debugging• Makes more for robust and user-friendly applications
47
Errors that are expected to occur
• Unreadable file• Out of disk space• Lost network connection• Invalid user input• …
49
Handle with return values and optional NSError
• A basic return value (BOOL or an object value) to indicate success• In cases where reporting the error is interesting, an NSError
• NSError is often returned “by reference,” as last argument■ NULL may be passed in
- (id)initWithContentsOfURL:(NSURL *)url encoding:(NSStringEncoding)enc error:(NSError **)error;
50
Sometimes NSError is passed via other means
• Sent to delegate
• Passed to completion block
- (void)webView:(UIWebView *)view didFailLoadWithError:(NSError *)error;
- (void)duplicateURLs:(NSArray *)URLs completionHandler:(void (^)(NSDictionary *newURLs, NSError *error))handler;
51
Not all APIs need an NSError
• NSError returns best confined to APIs where:■ The caller may want to take conditional action based on type of error■ The error may be reported to the user
■ In AppKit, use NSResponder API:
- presentError:- presentError:modalForWindow:delegate:
52
Errors often caused by misuse of APIs
• Out-of-bounds access
• Invalid argument type
• Invalid parameter value
obj = [myArray objectAtIndex:[myArray count]];
[someView setBackgroundColor:@“0.4, 0.1, 0.1”];
[myTextField setStringValue:nil];
53
• Not indicated via return values
• But by exceptions■ NSException
- (ErrorCode)setBackgroundColor:(UIColor *)color;
54
Handling exceptions
• Typically exceptions are not meant to be caught
@try { [myView setBackgroundColor:someObject];} @catch (NSException *) { [myView setBackgroundColor:[UIColor blackColor]];}
55
Handling exceptions
• You may still consider registering a top level exception handler■ Alert the user that something bad happened■ Give them a chance to save their work and quit the app
Cocoa Tips and Tricks MarinaTuesday 2:00PM
56
Thread safety for a single property
• Objective-C 2.0 properties are by default “atomic”■ But they can be made non-atomic:
• Atomic guarantees that in the presence of multiple threads that get or set a property, the property is set or retrieved fully■ Provides a basic, low-level of thread safety for a single property■ But it does not provide consistency between properties
@property (nonatomic, copy) NSString *title;
57
Often a good idea to leave properties atomic
• When to consider non-atomic■ Performance critical usages
■ Look for objc_getProperty() or objc_setProperty() in samples■ Where you might already use a higher level of synchronization
■ Locks■ Queues■ Single-threaded access
Cocoa Performance Techniques WWDC 2008Session 412
58
• Consistency• Performance• Safety• Reusability
■ Subclassing■ Categories■ Patterns for communicating changes
• Convenience
60
Why is it important?
• No need to reinvent the wheel• You only write the code that distinguishes your application• Pieces of your application can be reused elsewhere
61
Subclassing
• Fundamental object-oriented programming feature• Not very commonly used in Cocoa and Cocoa Touch for customization
■ Many classes are “concrete” and usable as-is■ Some classes are meant for subclassing: “abstract” or “semi-abstract”
62
Some classes are meant for subclassing
• NSObject, UI/NSView, UI/NSViewController, UI/NSResponder, NSDocument
• Identify methods meant for overriding
- [NSObject init]- [UIView drawRect:]- [UIResponder canBecomeFirstResponder]- [NSDocument readFromURL:ofType:error:] ...
63
• Some Foundation value classes are abstract, but usable■ NSString, NSData, NSArray, NSDictionary, …
• alloc/init methods return proper instances• But subclasses don’t work unless some methods are overridden
■ “Primitives”
64
Primitive methods
• Minimal API to implement a new subclass
@interface NSString : NSObject
- (NSUInteger)length;- (unichar)characterAtIndex:(NSUInteger)index; @end
65
Why are these classes abstract?
• We do not want to encourage subclassing these classes to add additional properties■ Changes the fundamental meaning of what the object stores
- length- characterAtIndex:
- length- characterAtIndex:- font
66
Why are these classes abstract?
NSString *string = ...; // “Hello”
RichString *richString = ...; // “Hello”, Helvetica
[string isEqual:richString]
[richString isEqual:string]
Sure!
No way!
67
Why would you subclass NSString, NSData, NSArray, …?
• Implement the primitives to provide alternate storage■ Optimized for a given backing store■ Load elements lazily
Cocoa Fundamentals Guide: “Class Clusters” http://developer.apple.com
69
Categories
• Language feature• Allows adding methods on existing classes
■ All instances are affected
• Enables■ Declaring additional methods in other header files■ Extending a class without subclassing
70
Example
• Both UIKit and AppKit add new functionality to NSString
@interface NSString (UIStringDrawing)
- (CGSize)drawInRect:(CGPoint)loc withFont:(UIFont *)font;- (CGSize)drawAtPoint:(CGPoint)loc withFont:(UIFont *)font;...@end
71
- length- characterAtIndex:
- drawInRect:withFont:- drawAtPoint:withFont:
- length- characterAtIndex:- drawInRect:withFont:- drawAtPoint:withFont:
- length- characterAtIndex:
NSString and UIStringDrawing Category
NSString and DrawableString Subclass
72
Patterns for communicating changes
• Delegation• Notification• Key-value observing• Target-action
Cocoa Fundamentals Guide: “Cocoa Design Patterns” http://developer.apple.com
73
Delegation
• Allows an object to act on behalf of another• Not a language feature
■ Classes explicitly support delegates
@interface UITextView
@property(assign) id<UITextViewDelegate> delegate;
@end
74
Delegate methods declared as a protocol
@protocol UITextViewDelegate @optional- (BOOL)textViewShouldBeginEditing:(UITextView *)text;- (BOOL)textViewShouldEndEditing:(UITextView *)text;- (void)textViewDidChangeSelection:(UITextView *)text;...@end
75
• Allows one object to help many others
• Allows proper subdivision of responsibility• Flexible
delegate
delegate
delegate
dataSource
76
Notifications
• Allows happenings to be broadcast to a set of unrelated observers• Observers observe, but don’t interfere• Not a language feature
■ NSNotificationCenter provides the facility■ Classes declare the notifications they post
NSString *const UIPasteboardChangedNotification;NSString *const NSWindowWillCloseNotification;NSString *const UIKeyboardDidShowNotification;
77
• Allows multiple observers• Indirection between objects enables observing of
■ Any notification from a particular object■ A specific notification from any object
- postNotification:
78
Key-value observing
• Allows objects to broadcast updates to values of individual properties• Not a language feature
■ Classes decide which properties they want to implement this for■ Automatic for key-value coding compliant properties
79
Target-Action
• Allows UI controls to indicate user interaction• Simple approach, well-suited for use in Interface Builder
■ Controls send their target a custom action
• Use of responder chain makes target-action flexible
80
• Defines three clear functional roles for objects• Each piece separately replaceable/customizable• Used for overall app design, as well as at subsystem level:
■ Cocoa text system■ Cocoa bindings architecture■ UITableView, NSTableView■ Cocoa Touch UIViewController
Model-View-Controller for iPhone OS Russian HillWednesday 10:15AM
Advanced Cocoa Text Tips & Tricks Russian HillWednesday 9:00AM
81
Convenience APIs
• APIs that simplify or combine a number of other calls into one
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)opts range:(NSRange)compareRange locale:(id)locale;
- (NSComparisonResult)compare:(NSString *)string;
86
Convenience APIs
• We usually consider convenience APIs only in cases where■ The implementation is more than two lines,■ There is additional value, or■ There is valuable abstraction
87
Additional value
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)opts range:(NSRange)compareRange locale:(id)locale;
- (NSComparisonResult)compare:(NSString *)string;
- (NSComparisonResult)compare:(NSString *)string { return [self compare:string options:0 range:NSMakeRange(0, [self length]) locale:nil];}
88
Additional value
• compare: allows easy use of sorting methods
• In fact we have more NSString comparison conveniences:
[myArray sortUsingSelector:@selector(compare:)];
- caseInsensitiveCompare:- localizedCompare:- localizedCaseInsensitiveCompare:- localizedStandardCompare:
89
Valuable abstraction
• This is currently documented to use:
• But the actual implementation will change over time
- localizedStandardCompare:
[string compare:otherStr options:NSCaseInsensitiveSearch |
NSNumericSearch | NSWidthInsensitiveSearch | NSForcedOrderingSearch range:NSMakeRange(0, [str length]) locale:[NSLocale currentLocale]];
90
Blocks
• Blocks do not enable anything that was impossible before• But they bring a lot of convenience
■ Ability to specify a piece of code inline■ Ability to capture state
91
Make compare variants less necessary
• Instead of
• Can now do
[myArray sortUsingComparator:^(id str1, id str2) { return [str1 compare:str2 options:NSNumericSearch]; }];
[myArray sortUsingFunction:myNumericSort context:NULL];
...
NSComparisonResult myNumericSort(id str1, id str2, void *ctxt) { return [str1 compare:str2 options:NSNumericSearch];}
92
New APIs for presenting sheets on NSSavePanel
• Leopard
• Snow Leopard
- (void)beginSheetForDirectory:(NSString *)path file:(NSString *)name modalForWindow:(NSWindow *)window modalDelegate:(id)delegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo;
- (void)beginSheetModalForWindow:(NSWindow *)window completionHandler:(void (^)(NSInteger result))blk;
93
New APIs for animations on UIView+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations;
94
New APIs for animations on UIView
• iPhone OS 3
• iOS 4
[UIView beginAnimations:nil context:NULL];[UIView setAnimationDuration:0.5];view.alpha = 0.0;[UIView commitAnimations];
[UIView animateWithDuration:0.5 animations:^{ view.alpha = 0.0; }];
Building Animation Driven Interfaces Pacific HeightsThursday 9:00AM
95
• Good API is a very important part of Cocoa and Cocoa Touch design• Modeling your APIs as Apple’s will allow your APIs to be
■ More predictable■ Widely reusable■ Better performing
• API Design is an evolving art
97
Bill DudneyFrameworks [email protected]
DocumentationCocoa Fundamentals GuideIntroduction to Coding Guidelines for CocoaAnd many more!http://developer.apple.com
Apple Developer Forumshttp://devforums.apple.com
98