The iPhone Developer's Cookbook(3)

概括性地介绍了OC的基础类等


Category
OC's built-in capability to expand already-existing classes is one of its most powerful features. This behavioral expansion is called a category. Categories extend class functionality without subclassing.
Categories add methods to existing classes even if you did not define that class in the first place and do not have the source code for that class.
To build a category, you declare a new interface. Specify the category name (it's arbitrary) within parentheses.
You cannot add new instance variables to a category interface as you could when subclassing. You are instead expanding a class's behavior.
eg:
Building an Orientation category for the UIDevice Class
@interface UIDevice (Orientation)
@property (nonatomic, readonly) BOOL isLandscape;
@end

@implementation UIDevice (Orientation)
- BOOL isLandscape
{
    return (self.orientation == UIDeviceOrientationLandscapeLeft) ||
        (self.orientation == UIDeviceOrientationLandscapeRight);
}
@end

Protocols
Delegates implement details that cannot be determined when a class is first defined.
Delegation basically provides a language that mediates contact between an object and its handler.

In OC, both delegation and data sourcing are produced by a system called protocols.
Protocols define a priori how one class can communicate with another. They contain a list of methods that are defined outside any class. Some of these methods are required.  Others are optional. Any class that implements the required methods is said to conform to the protocol.

You can use the @required and @optional keywords to declare a protocol to be of one form or the other. Any methods listed after an @required keyword are required; after an @optional keyword,  they are optional.

NSObject provides a respondsToSelector: method, which returns a Boolean YES if the object implements the method or NO otherwise.

The majority of protocol methods in the iPhone SDK are optional.

In OC, the core NSString class is immutable in Cocoa. That is, you can use strings to build other strings, but you can't edit the strings your already own. String constants are delineated by quote marks and the @ character.

NSHomeDirectory(), a function that returns a string with a path pointing to the application sandbox.

In Cocoa, most file access routines offer an atomic option.When you set the atomically parameter to YES, the iPhone writes the file to a temporary auxiliary and then renames it into place. Using an atomic write ensures that the file avoids corruption.

Using NSError class to store that error information and sends the localizedDescription selector to convert the information into a human-readable form. Whenever iPhone methods return errors, use this approach to determine which error was generated.

Converting Strings to Arrays
You can convert a string into an array by separating its components across some repeated boundary.
NSString *myString = @"one two three four five six seven eight";
NSArray *wordArray = [myString componentsSeparatedByString: @" "];
NSLog(@"%@", wordArray);

Requesting Indexed Substrings
As with standard C, array and string indices start at 0.
NSString *sub1 = [myString substringToIndex:7];
NSString *sub2 = [myString substringFromIndex:4];

Generating Substrings from Ranges
NSRange provides a structure that defines a section within a series. You use ranges with indexed items like strings and arrays.
NSRange r;
r.location = 4;
r.length = 2;
NSString *sub3 = [myString substringWithRange:r];

Search and Replace with Strings
NSRange searchRange = [myString rangeOfString:@"Five"];
if(searchRange.location != NSNotFound)
    NSLog(@"Range location: %d, length: %d", searchRange.location, searchRange.length];
Searches return range, which contain both a location and a length. Once you've found a range, you can replace a subrange with a new string.
NSLog(@"%@", [myString stringByReplacingCharactersInRange: searchRange withString: @"New String"]);

A more general approach lets you replace all occurrences of a given string.
myString = @"one* two*three*four*five*six";
NSString *replace = [myString stringByReplacingOccurrencesOfString: @" " withString: @" * "];

Changing Case
NSString *myString = @"Hello world. How do you do?";
NSLog(@"%@", [myString uppercaseString]);
NSLog(@"%@", [myString lowercaseString]);
NSLog(@"%@", [myString capitalizedString]);

Extracting Numbers from Strings
NSString *s1 = @"3.141592";
NSLog(@"%d", [s1 intValue]);
NSLog(@"%d", [s1 boolValue]);
NSLog(@"%f", [s1 floatValue]);
NSLog(@"%f", [s1 doubleValue]);

Mutable Strings
The NSMutableString class is a subclass of NSString. It offers you a way to work with strings whose contents can be modified. Once instantiated, you can append new contents to the string, allowing you to grow results before returning from a method.
NSMutableString *myMString = [NSMutableString stringWithString: @"Hello world. "];
[myMString appendFormat:@"The results are %@ now.", @"in"];
NSLog(@"%@", myMString);

NSNumber class lets you treat numbers as objects.
One of the biggest reasons for using NSNumber objects rather than ints, floats, and so forth, is that you can use them with Cocoa routines and classes.

The NSDecimalNumber class provides a handy object-oriented wrapper for base-10 arithmetic.

NSDate objects use the number of seconds since an epoch, that is a standardized universal time reference, to represent the current date. The iPhone epoch was at midnight on January 1, 2001. The standard Unix epoch took place at midnight on January 1, 1970.

Each NSTimeInterval represents a span of time in seconds, stored with subsecond floating-point precision.
// current time
NSDate *date = [NSDate date];

// time 10 seconds from now
date = [NSDate dateWithTimeIntervalSinceNow:10.0f];

You can compare dates by setting or checking the time interval between them.
// Sleep 5 seconds and check the time interval
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:5.0f]];
NSLog(@"Slept %f seconds", [[NSDate date] timeIntervalSinceDate:date]);
// Show the date
NSLog(@"%@", [date description]);

NSDateFormatter class.
// Produce a formatted string representing the current date
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
formatter.dateFormat = @"MM/dd/YY HH:mm:ss";
NSString *timestamp = [formatter stringFromDate:[NSDate date]];
NSLog(@"%@", timestamp];

Timer class
To disable a timer, send it the invalidate message; this release the timer object and removes it from the current runloop;
[timer invalidate];

Recovering Information from Index Paths
The NSIndexPath class is used with iPhone tables. It stores the section and row number for a user selection, that is, when a user taps on the table.

Collections
The iPhone primarily uses three kinds of collections:arrays, dictionaries, and sets.
Create arrays using the arrayWithObjects: convenience method, which returns an autorelease array. When calling this method, list any objects you want added to the array and finish the list with nil.(If you do not include nil in your list, you'll experience a runtime crash.)
NSArray *array = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];
Arrays are indexed starting with 0, up to one less than the count.Attempting to access[array objectAtIndex: array.count] causes an "index beyond bounds" exception and crashes.

The mutable form of NSArray is NSMutableArray. With mutable arrays, you can add and remove objects at will.

Checking Arrays
if([marray containsObject:@"Four"])
    NSLog(@"The index is %d", [marray indexOfObject:@"Four"]);

Converting Arrays into Strings
NSArray *array = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];
NSLog(@"%@", [array componentsJoinedByString:@" "];

NSDictionary class and NSMutableDictionary class.
Creating Dictionaries
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:@"1" forKey:@"A"];
[dict setObject:@"2" forKey:@"B"];
[dict setObject:@"1" forKey:@"C"];
NSLog(@"%@", [dict description]);

Searching Dictionaries
NSLog(@"%@", [dict objectForKey:@"A"]; // return @"1"
NSLog(@"%@", [dict objectForKey:@"F"]; // return nil

When you set a new object for the same key, Cocoa replaces the original object in the dictionary.

Removing Objects
[dict removeObjectForKey:@"B"];
Once removed, both the key and the object no longer appear in the dictionary.

Listing Keys
NSLog(@"The dictionary has %d object", [dict count]);
NSLog(@"%@", [dict allKeys]);

Arrays, sets and dictionaries automatically retain objects when they are added and release those objects when they are removed from the collection. Releases are also sent when the collection is deallocated. Collections do not copy objects. Instead, they rely on retain counts to hold onto objects and use them as needed.

Both arrays and dictionaries can store themselves into files using writeToFile: atomically: methods so long as the types within the collections belong to the set of NSData, NSDate, NSNumber, NSString, NSArray, and NSDictionary.
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/ArraySample.txt"];
if([array writeToFile:path atomically:YES])
    NSLog(@"File was written successfully");

To recover an array or dictionary from file, use the convenience methods arrayWithContentsOfFile: and dictionaryWithContentsOfFile:. If the methods return nil, the file could not be read.
NSArray *array = [NSArray arrayWithContentsOfFile:path];
NSLog(@"%@", newArray);

Building URLs
NSURL objects point to resources. These resources can refer to both local files and to URLs on the Web.
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/foo.txt"];
NSURL *url1 = [NSURL fileURLWithPath:path];
NSLog(@"%@", url1];

NSString *urlpath = @"http://ericasadun.com";
NSURL *url2 = [NSURL URLWithString:urlpath];
NSLog(@"%d characters read", [[NSString stringWithContentsOfURL:url2] length]);

NSData provides data objects that store and manage bytes. Often you fill NSData with the contents of a file or URL. The data returned can report its length, letting you know how many bytes were retrieved.
NSData *data = [NSData dataWithContentsOfURL:url2];
NSLog(@"%d", [data length]);

To access the core byte buffer that underlies an NSData object, use bytes. This returns a (const void*) pointer to actual data.
NSMutableData. You can keep growing mutable data by issuing appendData: to add the new information as it is received.


File Management
The iPhone's file manager is a singleton provided by the NSFileManager class. It can list the contents of folders to determine what files are found and perform basic file system tasks.

OC does not provide true multiple-inheritance, it offers a workaround that lets objects respond to message that are implemented in other classes. If you want your object to respond to another class's messages, you can add message forwarding to your applications and gain access to that object's methods.

Normally, sending an unrecognized message produces a runtime error, causing an application to crash. But before the crash happens, the iPhone's runtime system gives each object a second chance to handle a message. Catching that message lets you redirect it to an object that understands and can respond to that message.

OC provides this functionality through a process called message forwarding.
When you send a message to an object that cannot handle that selector, the selector gets forwarded to a forwardInvocation: method. The object send with this message, namely an NSInvocation instance stares the original selector and arguments that were requested. You can override forwardInvocation: and send that message on to another object.

Implementing Message Forwarding
To add message forwarding to your program, you must override two methods, namely, methodSignatureForSelector: and forwardInvocation:. The former creates a valid method signature for messages implemented by another class. The latter forwards the selector to an object that actually implements that message.
The first method returns a method signature for the requested selector.
The second method you need to override is forwardInvocation:.This method only gets called when an object has been unable to handle a message. This method gives the object a second change, allowing it to redirect that message. The method checks to see whether the message(self.carInfo) string responds to the selector.

Using Forwarded Messages
Calling nonclass messages like UTF8String and length produces compile-time warnings, which you can ignore.

Although invocation forwarding minics multiple inheritance, NSObject never confuses the two. Methods like respondsToSelector: and isKindOfClass: only look at the inheritance hierarchy and not at the forwarding change.

Reimplementing respondsToSelector: and isKindofClass: lets other class query your class.In return, the class announces that it responds to all string methods( in addition to its own) and that it is a "kind of" string, further emphasizing the pseudo-multiple inheritance approach.

Supereasy Forwarding

你可能感兴趣的:(developer)