Mac OS X Reference Library Apple Developer
Search
Document Generated: 2009-09-03 18:22:34 -0700
Foundation Framework Release Notes Copyright © 2010 Apple Inc. All Rights Reserved.


Foundation Framework Release Notes
(Covering Mac OS X SnowLeopard and iOS 4.0)



The Foundation Framework is a library of Objective-C classes that provide the infrastructure for object-based applications without graphical user interfaces.

This document describes the changes in Foundation Framework since Mac OS X release 10.5. Updates to the document since WWDC 2008, WWDC 2009, and various seeds are indicated in the section titles.

You can find release notes for the Application Kit as well as some notes on general backward compatibility issues, version handling, etc, here.


Backward Compatibility

One backward compatibility mechanism that is occasionally used in the frameworks is to check for the version of the system an application was built against, and if an older system, modify the behavior to be more compatible. This is done in cases where bad incompatibility problems are predicted or discovered; and most of these are listed below in these notes.

Typically we detect where an application was built by looking at the version of the system frameworks the application was linked against. Thus, as a result of relinking your application on Leopard, you might notice different behaviors, some of which might cause incompatibilities. In these cases because the application is being rebuilt, we expect you to address these issues at the same time as well. For this reason, if you are doing a small incremental update of your application to address a few bugs, it's usually best to continue building on the same build environment and libraries used originally.

In some cases, we provide defaults (preferences) settings which can be used to get the old or new behavior, independent of what system an application was built against. Often these preferences are provided for debugging purposes only; in some cases the preferences can be used to globally modify the behavior of an application by registering the values (do it somewhere very early, with -[NSUserDefaults registerDefaults]).



NSKeyedArchiver

Prior to 10.6, the archiver parameter to replacementObjectForKeyedArchiver: was always nil. For applications linked on or after 10.6, this parameter will be populated with the archiver as expected.


NSPropertyList

The following methods on NSPropertyListSerialization are now obsolete and will be deprecated in a future release:
+ (NSData *)dataFromPropertyList:(id)plist format:(NSPropertyListFormat)format errorDescription:(NSString **)errorString;
+ (id)propertyListFromData:(NSData *)data mutabilityOption:(NSPropertyListMutabilityOptions)opt
format:(NSPropertyListFormat *)format errorDescription:(NSString **)errorString;
The replacement methods are:
+ (NSData *)dataWithPropertyList:(id)plist format:(NSPropertyListFormat)format options:(NSPropertyListWriteOptions)opt error:(NSError **)error;
+ (id)propertyListWithData:(NSData *)data options:(NSPropertyListReadOptions)opt format:(NSPropertyListFormat *)format error:(NSError **)error;
+ (NSInteger)writePropertyList:(id)plist toStream:(NSOutputStream *)stream format:(NSPropertyListFormat)format
options:(NSPropertyListWriteOptions)opt error:(NSError **)error;
+ (id)propertyListWithStream:(NSInputStream *)stream options:(NSPropertyListReadOptions)opt
format:(NSPropertyListFormat *)format error:(NSError **)error;
The new methods provide better error handling, better conformance with the standard memory management rules, and better support for localization.

On the new methods, if the error parameter is non-NULL and an error occurs then it will be set to an autoreleased NSError describing the problem.

On the dataWithPropertyList:format:options:error: and writePropertyList:toStream:format:options:error: methods, the NSPropertyListWriteOptions parameter is currently unused and should be set to 0. The format option should be set to a NSPropertyListFormat.

On the propertyListWithData:options:format:error: and propertyListWithStream:options:format:error: methods, the NSPropertyListReadOptions parameter should be set to one of the NSPropertyListMutabilityOptions. If the format parameter is non-NULL, it will be filled out with the format of the read property list.


Bug Fix in NSAppleScript Running Garbage-Collected

In Mac OS 10.5 there was a bad bug in NSAppleScript that rendered it effectively incompatible with garbage collection. The symptoms were frequent crashes and spurious returning of errors. This bug has been fixed since Mac OS 10.5.3.

Bug Fix in -[NSUndoManager prepareWithInvocationTarget:] (New since November seed)

In earlier versions of Mac OS -[NSUndoManager prepareWithInvocationTarget:] always returned the receiving NSUndoManager. Because of the way Objective-C message forwarding works this meant that undo actions would not be recorded for messages which NSUndoManager itself can handle including, importantly, all messages implemented by NSObject or any category of NSObject. Instead the messages would just be handled by the NSUndoManager. This bug has been fixed in Mac OS 10.6.

Bug Fix in .sdef-Declared Scriptability

In Mac OS 10.4 and Mac OS 10.5 Cocoa Scripting's support for the "number" type was incomplete even though this type is one of the .sdef primitive types. The symptom of this was exceptions with descriptions that said things like "This instance of the class 'NSCFNumber' doesn't respond to -scriptingNumberDescriptor messages" and "+[NSNumber scriptingNumberWithDescriptor:]: unrecognized selector sent to class 0x26a7560." This bug has been fixed.

Bug Fix in General Scriptability

In all previous versions of Mac OS X -[NSTextStorage(NSScripting) words] was easily confused by numbers followed immediately by punctuation. The result was that invoking the method wouldn't return all of the words that it should, which of course affected the results of telling apps like TextEdit to return things like the "words of the front document." This bug has been fixed.


Sudden Termination - Fast Killing Of Applications (Updated since November seed)

Mac OS 10.6 includes a new mechanism that allows the operating system to log out or shut down more quickly by, whenever possible, killing applications instead of requesting that they quit themselves. Two new methods have been added to NSProcessInfo:
- (void)disableSuddenTermination;
- (void)enableSuddenTermination;
These methods disable or reenable the ability to be quickly killed. The default implementations of these methods increment or decrement, respectively, a counter whose value is 1 when the process is first created. When the counter's value is 0 the application is considered to be safely killable and may be killed by the operating system without any notification or event being sent to the process first. If an application's Info.plist has an NSSupportsSuddenTermination entry whose value is true then NSApplication invokes -enableSuddenTermination automatically during application launch, which typically renders the process killable right away. You can also manually invoke -enableSuddenTermination right away in, for example, agents or daemons that don't depend on AppKit. After that, you can invoke these methods whenever the process has work it must do before it terminates.

For example:
 - NSUserDefaults uses these to prevent process killing between the time at which a default has been set and the time at which the preferences file including that default has been written to disk.
 - NSDocument uses these to prevent process killing between the time at which the user has made a change to a document and the time at which the user's change has been written to disk.
 - You can use these whenever your application defers work that must be done before the application terminates. If for example your application ever defers writing something to disk, and it has an NSSupportsSuddenTermination entry in its Info.plist so as not to contribute to user-visible delays at logout or shutdown time, it must invoke -disableSuddenTermination when the writing is first deferred and -enableSuddenTermination after the writing is actually done.

Notice that -enableSuddenTermination is used to inform the operating system that the process can participate in the fast killing mechanism in the first place, and that it will be automatically invoked once for that purpose if you put an NSSupportsSuddenTermination entry whose value is true in your application's Info.plist. Notice that it is also used to balance previous invocations of -disableSuddenTermination.

Debugging tip: you can find out the value of the counter mentioned in the above comment by executing 'print (long)[[NSClassFromString(@"NSProcessInfo") processInfo] _suddenTerminationDisablingCount]' in gdb (using the Xcode Debugger Console, for instance). Do not attempt to invoke or override -_suddenTerminationDisablingCount in your application. It is there just for this debugging purpose, and may disappear at any time.

Instruments also has an instrument that lets you track invocations of these methods.


Automatic Removal of Finalized Key-Value Observers When Running Garbage-Collected (New since November seed)

With the addition of support for Objective-C garbage collection to Foundation in Mac OS 10.5 one of the basic rules of key-value observing (KVO) remained, and still applied to garbage-collected applications: all invocations of KVO's -addObserver:forKeyPath:options:context: method must be balanced by invocations of -removeObserver:forKeyPath: or KVO will leak memory. (KVO logs when it senses failure to follow this rule but only when running non-garbage-collected.) The same rule applied to use of KVO's NSArray batched observer registration methods. This resulted in situations in which classes of observers had to have -finalize methods just to do observer deregistration when they otherwise would not have to. -finalize methods are supposed to be rarer than that. In Mac OS 10.6, explicit removal of observers when they're finalized is now never necessary. KVO automatically removes observers as they're collected. Actually, in Mac OS 10.6 all invocations of -[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:] and -[NSArray(NSKeyValueObserverRegistration) removeObserver:fromObjectsAtIndexes:forKeyPath:] do virtually nothing when either the receiver or the observer is being finalized (so it's not very bad for performance to leave them there in applications that still have to run on Mac OS 10.5).

One thing has not changed in Mac OS 10.6: for performance reasons you should not leave an observer registered with objects that no longer matter at all to the observer. When observing the properties of objects in a collection whose membership changes as the application runs, it's best to follow a pattern of making that collection the value for a to-many relationship of some parent object and adding and removing your observer of the individual objects as they become related and unrelated. See for example Sketch's SKTGraphicView class, in particular when it invokes its own -startObservingGraphics: and -stopObservingGraphics: methods. If you instead assume that observed objects will just go away when there are no references to them other than observation then your application might use more memory than you expect because observed objects will not be collected as soon as you expect. You can depend on KVO to cleanly handle observers and observed objects being collected, and you can depend on KVO to not cause observers to go uncollected, but you cannot depend on an observed object being collected before its observers, even if no other objects reference the observed object.

Bug Fixes in Debugging of Objects Being Deallocated With Observers Still Registered When Not Running Garbage-Collected (Updated since March 2009 Seed)

In Mac OS 10.3 through 10.5 there was a bug in which a valuable debugging feature of KVO was not triggered when an object observing itself did not remove itself as an observer of itself during deallocation. This bug has been fixed in Mac OS 10.6. When this happens Foundation now logs something like "An instance 0x100771010 of class MySelfObservingClass was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info:…"

There was another bug in which this logging was done spuriously when an object observed by a second object was deallocated, its deallocation caused the release of the second object, and the second object correctly unregistered itself as an observer of the first object at that time due to its own deallocation. This bug has also has been fixed in Mac OS 10.6.

To summarize, KVO's test for objects being deallocated with observers still registered exhibited both false negatives and false positives, and both kinds of mistake have been fixed.


New NSPurgeableData class

Mac OS 10.6 includes an NSMutableData subclass called NSPurgeableData that takes advantage of the new purgeable memory feature. NSPurgeableData objects conform to the NSDiscardableContents protocol, whose description is forthcoming.

For NSPurgeableData, if -beginContentAccess returns NO, then the NSPurgeableData's bytes have been purged and the bytes are effectively inaccessible. Note that NSPurgeableData objects are "accessed" upon creation, so -endContentAccess must be called after creation to make the data purgeable.


NSData copyWithZone: changed (New since WWDC 2008)

Prior to Mac OS 10.6, when -copyWithZone: was invoked on any CFData instance through toll-free bridging, the method would always return a new NSData instance containing a copy of the original bytes. For applications linked on or after 10.6, this method will retain and return the original instance, instead of copying, when invoked on an immutable CFData. If you need to create an actual copy of a CFData instance, use CFDataCopy() or -dataWithData:.


-[NSData getBytes:range:] and NSRangeException (New since WWDC 2008)

Prior to Mac OS 10.6, -[NSData getBytes:range:] did not properly raise an NSRangeException for ranges which start inside the NSData's bytes, but end outside them. Instead it filled the provided buffer up to the end of the NSData. For applications linked on or after Mac OS 10.6, this method will now properly raise an NSRangeException.


NSNumberFormatter, NSDateFormatter, and -getObjectValue:forString:errorDescription: (New since WWDC 2008)

Prior to Mac OS 10.6, both NSNumberFormatter's and NSDateFormatter's implementation of -getObjectValue:forString:errorDescription: would return YES and a parsed object value if only part of the string could be parsed. This is problematic because with this API you cannot be sure what portion of the string was parsed. For applications linked on or after Mac OS 10.6, this method instead returns an error if part of the string cannot be parsed. You can use -getObjectValue:forString:range:error: to get the old behavior; this method returns the range of the substring that was successfully parsed.


Formal Protocol Adoption (New since WWDC 2008)

In Mac OS 10.6, Foundation switched to using formal protocols for all delegates to provide better compile-time type checking. Required protocol methods are marked with @required, where possible. The rest are marked with @optional.

The affected classes are
• NSConnection
• NSKeyedArchiver
• NSMetadataQuery
• NSNetService
• NSNetServiceBrowser
• NSPort
• NSMachPort
• NSSpellServer
• NSStream
• NSXMLParser

The changes will introduce new warnings in code using these classes' delegates. Fortunately, the changes needed to correct these warnings are fairly simple.

• Your delegate classes need to declare conformance to the new protocols. For example:
@interface MyDelegate : NSObject <NSMetadataQueryDelegate> ... @end
• Sending messages to [foo delegate] that are not in the delegate's protocol will generate a warning. This is not generally recommended since there are no guarantees about the delegate's class. However, you may work around this by casting the result of [foo delegate] to id. Also, you should always perform a respondsToSelector: check before invoking a method on [foo delegate] that is not an @required method in the protocol.

• If you have a subclass of one of these classes that adds additional delegate methods you must also create a subprotocol and override -delegate and -setDelegate:. For example:
@protocol MyStreamDelegate;
@interface MyStream : NSStream
- (id <MyStreamDelegate)delegate;
- (void)setDelegate:(id <MyStreamDelegate>)delegate;
@end
@protocol MyStreamDelegate <NSStreamDelegate>
- (void)additionalDelegateMethod;
@end
@implementation MyStream
- (id <MyStreamDelegate)delegate {
    return (id <MyStreamDelegate>)[super delegate];
}
- (void)setDelegate:(id <MyStreamDelegate>)delegate {
    [super setDelegate:delegate];
}
@end
• If you need to target Leopard or Tiger with the same sources, you should conditionally declare empty protocols, or else the compiler will complain about missing protocols declarations. For example:
#if MAC_OS_X_VERSION_10_6 > MAC_OS_X_VERSION_MAX_ALLOWED
@protocol NSConnectionDelegate <NSObject> @end
#endif
`

Deprecating unsafe buffer-taking methods (New since November seed)

The following methods will deprecated in the next release of Mac OS.
-[NSString getCharacters:]
-[NSData getBytes:]
-[NSArray getObjects:]
These have been identified as unsafe. Typically, the buffers passed in to these methods are sized relative to the result from -count or -length. However, it is possible for the receiver to be mutated from another thread between these method calls. This may potentially cause a buffer overrun. To prevent this, you should use the following methods instead:
-[NSString getCharacters:range:]
-[NSData getBytes:length:] or -[NSData getBytes:range:]
-[NSArray getObjects:range:]

NSXMLParser fatal errors (New since November seed)

Before Mac OS 10.6, NSXMLParser would sometimes try to continue parsing after a fatal error. For applications linked on SnowLeopard or later, NSXMLParser will now abort parsing after reporting a fatal error.

For compatibility's sake, you can restore the pre-SnowLeopard behavior by setting the environment variable NSXMLParserContinueParsingAfterFatalError to YES. However, you should eliminate any dependency on this behavior as soon as possible.


NSData rangeOfData:withOptions:range: (New since November seed)

NSData now has a method that will efficiently search its contents:
    - (NSRange)rangeOfData:(NSData *)dataToFind
options:(NSDataSearchOptions)mask
range:(NSRange)searchRange;
The semantics are nearly identical to NSString's rangeOfString:withOptions:range:. The only significant difference is the lack of 'case insensitive' and 'literal' search options, which are only applicable to strings.


NSFileManager (New since November seed)

The following methods on NSFileManager now throw exceptions in Mac OS 10.6:
    - (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error;
    - (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error;
    - (BOOL)linkItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error;
    - (BOOL)copyItemAtURL:(NSURL *)srcURL toURL:(NSURL *)dstURL error:(NSError **)error;
    - (BOOL)moveItemAtURL:(NSURL *)srcURL toURL:(NSURL *)dstURL error:(NSError **)error;
    - (BOOL)linkItemAtURL:(NSURL *)srcURL toURL:(NSURL *)dstURL error:(NSError **)error;
For all applications, these methods will throw an NSInvalidArgumentException if dstPath or dstURL is nil. For applications linked on Mac OS 10.6 or later, these methods will throw an NSInvalidArgumentException if srcPath or srcURL nil.



NSString path completion (New since WWDC 2008)

NSString's completePathIntoString:caseSensitive:matchesIntoArray:filterTypes: method previously did not correctly take the case-sensitive flag into account (specifically, much of the behavior defaulted to case-sensitive even if the flag was set to NO). This is now fixed; the entire path is matched case-insensitively if specified. (Note that on a case-insensitive filesystem like most HFS+ drives, case-sensitive completion will still match the path case-insensitively; only the last component will be matched case-sensitively. This is a limitation of the filesystem.)


NSDecimal (New since WWDC 2008)

NSDecimal and NSDecimalNumber now correctly report the zeroth power of a negative number (e.g. [someNegative decimalNumberByRaisingToPower:0]) to be 1, instead of -1.


NSIndexSet (New since WWDC 2008)

NSIndexSet can now safely be used on multiple threads. Like other collection classes, though, mutations to index sets are not thread-safe, so you must still synchronize access to any index sets that may change. If you want to ensure an index set is immutable, you should make an immutable copy.


Text Checking (Updated since WWDC 2008)

Snow Leopard includes a new facility known as text checking, which provides a unified interface for a variety of types of checking, including spell checking, grammar checking, URL detection, smart quotes, date and address detection via Data Detectors, and others. Among other things, this facility allows for the automatic identification of the languages used in a piece of text, so that spellchecking can proceed without the user having to label text as to language.

The basic interface for this facility is now available in AppKit via NSSpellChecker (see the AppKit release notes for details). Foundation contains two new classes intended to be used as part of this feature: NSTextCheckingResult and NSOrthography.

An instance of NSTextCheckingResult represents something that has been found during checking--a misspelled word, a sentence with grammatical issues, a detected URL, a straight quote to be replaced with curly quotes, and so forth. This is an immutable value class intended to be passed back as elements of the array returned to clients of the text checking APIs. Each instance has at a minimum a checking type showing the sort of item noted, and a range within the string being checked to which the result applies. There are currently 10 system-defined checking types, with space reserved for 22 more, and for 32 additional custom text checking types to be defined by clients. NSTextCheckingResult itself is a semi-abstract superclass; any custom result types would usually define a suitable subclass to hold the appropriate information.

NSOrthography is a class used to describe the linguistic content of a piece of text, especially for the purposes of spelling and grammar checking. It describes (a) which scripts the text contains, (b) a dominant language and possibly other languages for each of these scripts, and (c) a dominant script and language for the text as a whole. This is an immutable value class intended to be passed back as part of the results of automatic language identification, or passed in as a starting point for that identification.

For the purposes of NSOrthography, scripts are uniformly described by standard four-letter tags (Latn, Grek, Cyrl, etc.) with the supertags Jpan and Kore typically used for Japanese and Korean text, Hans and Hant for simplified and traditional Chinese text; the tag Zyyy is used if a specific script cannot be identified. Languages are uniformly described by BCP-47 tags, preferably in canonical form; the tag und is used if a specific language cannot be determined.

In addition, there is a new delegate method on NSSpellServer, which an NSSpellServer delegate in a spelling checker can use to perform spelling and grammar checking simultaneously when so requested by the new text checking methods on NSSpellChecker, as well as specifying autocorrection results.
- (NSArray *)spellServer:(NSSpellServer *)sender
checkString:(NSString *)stringToCheck
offset:(NSUInteger)offset
types:(NSTextCheckingTypes)checkingTypes
options:(NSDictionary *)options
orthography:(NSOrthography *)orthography
wordCount:(NSInteger *)wordCount;
The return value should be an array of NSTextCheckingResult objects, and the other arguments generally correspond to those for the new NSSpellChecker methods. The results should be of the orthography, spelling, grammar, or correction types, as specified by the checkingTypes. The string passed in to this method may be a substring of the string passed in to NSSpellChecker, and the offset argument represents the offset of that substring within the entire string; it should be added to the origin of the range for any NSTextCheckingResult returned. The orthography argument represents the identified orthography of the string being passed in to this method.


Learned Words (New since WWDC 2008)

The format for the learned words lists used by the spellchecker has not previously been documented. There are two types of learned word lists, both of which are stored as UTF-8 plain text documents in ~/Library/Spelling. The first type consists of those words learned specifically in the context of a particular language; these are stored in files named by the abbreviation for that language as specified in the NSLanguages array in the spellchecker's Info.plist. The second type consists of those words learned outside of the context of a particular language; these are stored in a single file named LocalDictionary. In any case, the files consist of lists of learned words (case-insensitive), one per line, separated by newlines (\n, U+000A). (Embedded nulls can also be used in place of the newlines, and were so used prior to Snow Leopard, but newlines are now preferred.) If a particular word appears more than once in a given file, it is treated as learned if and only if it appears an odd number of times. The spell checking machinery will occasionally update these files to be automatically normalized into a standard form, with each string appearing at most once.


URL-Based Methods for NSBundle

To reduce impedance mismatch with other methods taking or returning URLs, NSBundle now has URL-based equivalents of its original path-based methods. The arguments generally parallel those of the existing path-based methods, but the names in some cases have been changed to reflect current standards or to avoid terminology that has been found to be confusing. The new methods are:
+ (NSBundle *)bundleWithURL:(NSURL *)url;
- (id)initWithURL:(NSURL *)url;
- (NSURL *)bundleURL;
- (NSURL *)resourceURL;
- (NSURL *)executableURL;
- (NSURL *)URLForAuxiliaryExecutable:(NSString *)executableName;
- (NSURL *)privateFrameworksURL;
- (NSURL *)sharedFrameworksURL;
- (NSURL *)sharedSupportURL;
- (NSURL *)builtInPlugInsURL;
+ (NSURL *)URLForResource:(NSString *)name withExtension:(NSString *)ext subdirectory:(NSString *)subpath inBundleWithURL:(NSURL *)bundleURL;
+ (NSArray *)URLsForResourcesWithExtension:(NSString *)ext subdirectory:(NSString *)subpath inBundleWithURL:(NSURL *)bundleURL;
- (NSURL *)URLForResource:(NSString *)name withExtension:(NSString *)ext;
- (NSURL *)URLForResource:(NSString *)name withExtension:(NSString *)ext subdirectory:(NSString *)subpath;
- (NSURL *)URLForResource:(NSString *)name withExtension:(NSString *)ext subdirectory:(NSString *)subpath localization:(NSString *)localizationName;
- (NSArray *)URLsForResourcesWithExtension:(NSString *)ext subdirectory:(NSString *)subpath;
- (NSArray *)URLsForResourcesWithExtension:(NSString *)ext subdirectory:(NSString *)subpath localization:(NSString *)localizationName;


NSXMLNode and -setObjectValue:

NSXMLNode defines the -setObjectValue: method which would automatically transform non-NSString arguments into NSStrings to use as the value of the NSXMLNode object.

A long-standing bug in the number transformation code has been fixed in Mac OS X 10.6 which will affect output of XML files. Prior to SnowLeopard, NSXMLNode would improperly and inconsistently format NSNumbers passed in to -setObjectValue:. For applications linked on or after Mac OS X 10.6, NSXMLNode will use correct scientific notation for all NSNumbers passed in to -setObjectValue:. Applications linked against SDKs prior to Mac OS X 10.6 will get the original (possibly incorrect) behavior.

As a rule, if you require a particular format for any value in your XML document, you should format the data yourself as a string and then use -[NSXMLNode setStringValue:]. This guarantees that the text generated is in a format you control directly.

+[NSXMLNode namespaceWithName:stringValue:] (New since November seed)

For applications linked on SnowLeopard or later, +[NSXMLNode namespaceWithName:stringValue:] will now throw if the 'name' parameter is nil.


NSURL

There are significant API additions to NSURL to enable more efficient file property manipulation as well as additional behaviors. More description for this is forthcoming.

We have added some NSURL-based parallel APIs to places where we had only NSString-based APIs for referencing files. We intend to continue with this to make sure that all file referencing can take place via NSURLs, without the need to convert to other types such as strings or FSRefs.


NSFileManager URL-based file operations

In Mac OS X 10.6 "SnowLeopard", NSFileManager offers implementations of the common file operations that are based on NSURLs rather than paths represented by NSStrings. This eliminates some API mismatch when working primarily with AppKit APIs which primarily use NSURLs.

These methods are now available:
- (BOOL)copyItemAtURL:(NSURL *)srcURL toURL:(NSURL *)dstURL error:(NSError **)error;
- (BOOL)moveItemAtURL:(NSURL *)srcURL toURL:(NSURL *)dstURL error:(NSError **)error;
- (BOOL)linkItemAtURL:(NSURL *)srcURL toURL:(NSURL *)dstURL error:(NSError **)error;
- (BOOL)removeItemAtURL:(NSURL *)URL error:(NSError **)error;
The corresponding delegate methods are also available - see the NSFileManager.h header for more details.

NSFileManager mounted volume discovery (New since November seed)

It is now possible to get a list of the currently mounted volumes and at the same time get properties of those volumes using the following instance method on NSFileManager:
- (NSArray *)mountedVolumeURLsIncludingResourceValuesForKeys:(NSArray *)propertyKeys
options:(NSVolumeEnumerationOptions)options;
The property keys are those listed in the NSURL.h header as being volume property keys.

The return value is an NSArray of NSURL instances whose resource caches have been pre-populated with the requested resource values.

The options are:
enum {
NSVolumeEnumerationSkipHiddenVolumes = 1L << 1,
NSVolumeEnumerationProduceFileReferenceURLs = 1L << 2
}
typedef NSUInteger NSVolumeEnumerationOptions;
This call may block if I/O is required to determine values for the requested keys.

NSFileManager directory enumeration changes (New since November seed)

NSFileManager now offers URL-based directory enumeration similar to the mounted volume discovery above.

An NSDirectoryEnumerationOptions typedef describes the options:
enum {
NSDirectoryEnumerationSkipsSubdirectoryDescendants = 1L << 0,
NSDirectoryEnumerationSkipsPackageDescendants = 1L << 1,
NSDirectoryEnumerationSkipsHiddenFiles = 1L << 2
};
typedef NSUInteger NSDirectoryEnumerationOptions;
For shallow directory enumerations, the following method is now available:
- (NSArray *)contentsOfDirectoryAtURL:(NSURL *)url
includingPropertiesForKeys:(NSArray *)keys
options:(NSDirectoryEnumerationOptions)mask
error:(NSError **)error;
which returns an NSArray of NSURL instances representing the contents of the directory rooted at url. You can also provide an NSArray of keys of attributes to retrieve during the enumeration (these are the keys specified in <Foundation/NSURL.h>). Because this method provides a shallow enumeration, the only flag which makes sense to pass as an option is NSDirectoryEnumerationSkipsHiddenFiles. If an error occurs, the return value will be a nil array and the error parameter will be set to an appropriate NSError in the Cocoa error domain.

For deep directory enumerations, there is a new method on NSFileManager to return an NSDirectoryEnumerator which vends NSURLs:
- (NSDirectoryEnumerator *)enumeratorAtURL:(NSURL *)url
includingPropertiesForKeys:(NSArray *)keys
options:(NSDirectoryEnumerationOptions)mask
errorHandler:(BOOL (^)(NSURL *url, NSError *error))handler;
The url and keys parameters are as above. The mask parameter can take any of the flags defined in the NSDirectoryEnumerationOptions typedef. If an error occurs during enumeration, the handler block is invoked, which will be passed the url on which the error occurred and the error. If no handler is provided, the error will be skipped and enumeration will continue.

For both of these methods, if you wish to only receive the URLs and no other attributes, then pass '0' for 'options' and an empty NSArray ('[NSArray array]') for 'keys'. If you wish to have the property caches of the vended URLs pre-populated with a default set of attributes, then pass '0' for 'options' and 'nil' for 'keys'.

NSFileManager file system item replacement (New since November seed)

In Mac OS X 10.6 "SnowLeopard", NSFileManager provides an NSURL-based mechanism for replacing one filesystem object with another:
- (BOOL)replaceItemAtURL:(NSURL *)originalItemURL
withItemAtURL:(NSURL *)newItemURL
backupItemName:(NSString *)backupItemName
options:(NSFileManagerItemReplacementOptions)options
resultingItemURL:(NSURL **)resultingURL error:(NSError **)error;
This method returns YES if the replacement operation was successful. resultingURL will be populated with the URL which points at the new item. resultingURL may be the same as originalItemURL if the replacement could be made without having to create a new filesystem object. resultingURL may be different than originalItemURL if the replacement could not be made without having to create a new object (e.g. going from an rtf document to an rtfd requires the creation of a new item - in this case, resultingURL would locate the newly-created rtfd).

By default, the creation date, permissions, Finder label and color, and Spotlight comments of the original item will be preserved on the resulting item.

If backupItemName is provided, that name will be used to create a backup of the original item. The backup will be placed in the same directory as the original item. Should an error occur during the creation of the backup item, the operation will fail. If there is already an item with that name, the item will be removed.

NSFileManagerItemReplacementOptions is defined as follows:
enum {
NSFileManagerItemReplacementUsingNewMetadataOnly = 1L << 0,
NSFileManagerItemReplacementWithoutDeletingBackupItem = 1L << 1
}
typedef NSUInteger NSFileManagerItemReplacementOptions;
Pass 0 to get the default behavior which uses only the metadata from the new item, adjusting some properties from the original item (as above). In most cases, 0 should be passed.

NSFileManagerItemReplacementUsingNewMetadataOnly means metadata on the resulting item will be taken entirely from the new item.

NSFileManagerItemReplacementWithoutDeletingBackupItem flag causes -replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error: to leave the backup item in place if the operation is successful.

A new domain selector, NSItemReplacementDirectory, has been added for use with -[NSFileManager URLForDirectory:inDomain:appropriateForURL:create:error:]. It returns an NSURL locating the most appropriate directory for use with this method. You should write your new item into this directory.

If an error occurs in replacing a filesystem item and the original item has been left in neither the original location nor the temporary location, the NSError returned will contain a user info dictionary with the NSFileOriginalItemLocationKey key and its value will be an NSURL instance which locates the item. The error code is one of the various NSFile* errors already present in <Foundation/FoundationErrors.h>.


NSTask (New since WWDC 2008)

In SnowLeopard, the following method has been added to NSTask:
- (NSTaskTerminationReason)terminationReason;
which returns one of the following:
enum {
    NSTaskTerminationReasonExit = 1,
    NSTaskTerminationReasonUncaughtSignal = 2
};
typedef NSInteger NSTaskTerminationReason;
This allows a client to distinguish between the child process exiting cleanly and the child process ending because it received a signal it did not or could not handle.

If -[NSTask terminationReason] is called prior to task termination, an exception is thrown.


NSURL keyed archiving (New since February 2009 seed)

Mac OS X 10.6 "SnowLeopard" introduces file reference URLs; URLs which track by a file system item's identity rather than its path. Because file reference URLs do not function after certain file system or other events (e.g. login/logout or remount of a file system), file reference URLs must be used sparingly and encoded carefully.

When asked to perform keyed archiving, file reference URLs will encode their minimal bookmark data and when decoded will resolve to a file path URL (if you wish to receive a file reference URL from this, please call -[NSURL fileReferenceURL] on the resulting item).


NSURL Path Utilities (New since November seed)

NSURL has new methods for common path manipulations, defined in the NSURLPathUtilities category on NSURL:
+ (NSURL *)fileURLWithPathComponents:(NSArray *)components;
- (NSArray *)pathComponents;
- (NSString *)lastPathComponent;
- (NSString *)pathExtension;
- (NSURL *)URLByAppendingPathComponent:(NSString *)pathComponent isDirectory:(BOOL)isDirectory;
- (NSURL *)URLByAppendingPathComponent:(NSString *)pathComponent;
- (NSURL *)URLByDeletingLastPathComponent;
- (NSURL *)URLByAppendingPathExtension:(NSString *)pathExtension;
- (NSURL *)URLByDeletingPathExtension;
With path-based file: scheme URLs, the above methods operate similarly to the NSPathUtilities category methods on NSString. When file reference URLs (e.g. file:///.file/id=103.3747951) are sent these messages, a file reference URL will be returned which has been appropriately modified. fileURLWithPathComponents: will always return a path-based file: scheme URL.

For example, when sending the URLByAppendingPathComponent:isDirectory: message to a file reference URL, you would get the file reference URL as the base with the relative portion being the string passed as the pathComponent parameter. This creates a file reference URL which tracks the parent directory by filesystem identity, but locates a file of a specific name within that directory.

These conversions occur only when necessary. If the operation can be safely performed by manipulating the string of the relative portion of the NSURL instance, then these methods will do so. These conversions guarantee that the NSURL instance that is returned has the same base type as the original NSURL. If the base of the original NSURL instance was a file reference URL, then the base of the new NSURL instance will be a file reference URL.

If there is no last path component or path extension, the first two methods return the empty string (@"").

The following methods work only on file: scheme path-based URLs; for file reference URLs or for non-file: scheme URLs, these methods return the URL unchanged:
- (NSURL *)URLByStandardizingPath;
- (NSURL *)URLByResolvingSymlinksInPath;
lastPathComponent is not suitable for display to the user. You should use NSURL's getResourceValue:forKey:error: and pass NSURLLocalizedNameKey for the key.

pathExtension should not be used to determine the type of the file. You should instead use NSURL's getResourceValue:forKey:error: and pass NSURLTypeIdentifierKey as the key.


NSHost (New since November seed)

NSHost now provides a method to retrieve the name of the computer as specified in the "Sharing" preferences pane.
- (NSString *)localizedName;
This is the name that is used in the Finder sidebar and as the default name when publishing NSNetServices. This method only returns an NSString when sent to the +[NSHost currentHost] instance; all other instances currently return nil.


NSUserDefaults (new since February seed)

NSUserDefaults now has methods for setting and reading NSURLs as values.
- (void)setURL:(NSURL *)url forKey:(NSString *)key;
- (NSURL *)URLforKey:(NSString *)key;
When an NSURL is stored using -[NSUserDefaults setURL:forKey:], some adjustments are made:

1. Any non-file URL is written by calling +[NSKeyedArchiver archivedDataWithRootObject:] using the NSURL instance as the root object.

2. Any file reference file: scheme URL will be treated as a non-file URL, and information which makes this URL compatible with 10.5 systems will also be written as part of the archive as well as its minimal bookmark data.

3. Any path-based file: scheme URL is written by first taking the absolute URL, getting the path from that and then determining if the path can be made relative to the user's home directory. If it can, the string is abbreviated by using stringByAbbreviatingWithTildeInPath and written out. This allows pre-10.6 clients to read the default and use -[NSString stringByExpandingTildeInPath] to use this information.

When an NSURL is read using -[NSUserDefaults URLForKey:], the following logic is used:

1. If the value for the key is an NSData, the NSData is used as the argument to +[NSKeyedUnarchiver unarchiveObjectWithData:]. If the NSData can be unarchived as an NSURL, the NSURL is returned otherwise nil is returned.

2 If the value for this key was a file reference URL, the file reference URL will be created but its bookmark data will not be resolved until the NSURL instance is later used (e.g. at -[NSData initWithContentsOfURL:]).

3. If the value for the key is an NSString which begins with a ~, the NSString will be expanded using -[NSString stringByExpandingTildeInPath] and a file: scheme NSURL will be created from that.

Notes about persistence of NSURL and file reference URLs

When using NSURL instances to refer to files within a process, it's important to make the distinction between location-based tracking (file: scheme URLs that are basically paths) versus filesystem identity tracking (file: scheme URLs that are file reference URLs). When persisting an NSURL, you should take that behavior into consideration. If your application tracks the resource being located by its identity so that it can be found if the user moves the file, then you should explicitly write the NSURL's bookmark data or encode a file reference URL.

If you want to track a file by reference but you require explicit control over when resolution occurs, you should take care to write out bookmark data to NSUserDefaults rather than rely on -[NSUserDefaults setURL:forKey:]. This allows you to call +[NSURL URLByResolvingBookmarkData:options:relativeToURL:bookmarkDataIsStale:error:] at a time when you know your application will be able to handle the potential I/O or required user interface interactions.


defaults command

The defaults command-line tool is now able to print the by-host identifier used for a particular computer. This identifier is the string that is used for preferences filenames in the user's Library/Preferences/ByHost directory. You may print this identifier by using the following command-line invocation:
    defaults printHostIdentifier

NSXMLParser (new since February 2009 seed)

For applications linked on or after SnowLeopard, NSXMLParser will stop parsing when it encounters a fatal error; by not stopping applications would sometimes crash due to inconsistent parser state.

Applications linked on SDKs prior to 10.6 will continue to get the old behavior. New applications should expect that parsing will end when an error occurs.



New NSCalendarUnit

A new "quarter" calendar unit (NSQuarterCalendarUnit) has been added to the set of NSCalendarUnits (NSCalendar.h). A new pair of accessor methods (-quarter/-setQuarter:) have also been added to NSDateComponents.


New calendars (Updated since November seed)

Four new calendar constants (NSRepublicOfChinaCalendar, NSPersianCalendar, NSIndianCalendar, NSISO8601Calendar) have been added (NSLocale.h). The ISO8601 calendar is not yet implemented. A Chinese calendar can be created, and one can do calendrical calculations with it, but it should not be used for formatting as the necessary underlying functionality is not functioning correctly yet.


New NSTimeZone class method

A new method, +setAbbreviationDictionary:, has been added (NSTimeZone.h). This corresponds to the CFTimeZoneSetAbbreviationDictionary() function in the CFTimeZone API.


NSConnection method deprecation

The +defaultConnection method in NSConnection has been deprecated. This provided a singleton connection object per thread. For what should be obvious reasons, it was never a particularly good idea to use this method/connection unless you had absolute certainty that no one else was using it (or going to use it), which was problematic. Just use [[NSConnection new] autorelease] instead (in conjunction with NSThread's thread dictionary if you must have one stored per-thread, though as a design point that may cause you problems in the future, so it would be best to avoid a per-thread connection).


NSMutableArray method deprecation

The -removeObjectsFromIndices:numIndices: method has been deprecated. Use -removeObjectsAtIndexes: instead.


NSDate method deprecations and additions

The -addTimeInterval: method of NSDate has been deprecated and replaced with -dateByAddingTimeInterval: (NSDate.h). The new method is available from 10.5 onward.

The methods +dateWithTimeInterval:sinceDate: and -initWithTimeIntervalSince1970: have been added to NSDate (NSDate.h). These new methods are available from 10.4 onward.


Method declarations moved

The declarations for the keyed archiving geometry struct category methods on NSCoder – -encodePoint:forKey:, -encodeSize:forKey:, -encodeRect:forKey:, -decodePointForKey:, -decodeSizeForKey:, -decodeRectForKey: – moved from NSKeyedArchiver.h to NSGeometry.h.

The declaration for the NSDate method -descriptionWithLocale: moved from a category in NSCalendarDate.h to NSDate.h.


New convenience methods on NSDateFormatter, NSNumberFormatter

A new class method, +localizedStringFromDate:dateStyle:timeStyle:, has been added to NSDateFormatter to produce a localized formatted date string representation in fewer lines of code than the previous sequence involving creation of an NSDateFormatter.

A new class method, +localizedStringFromNumber:numberStyle:, has been added to NSNumberFormatter to produce a localized formatted number string representation in fewer lines of code than the previous sequence involving creation of an NSNumberFormatter.


Privatized instance variables

In several classes, the declarations of the instance variables have been fixed to mark them private, protected or package where previously the permissions were more permissive. This includes the classes NSIndexPath, NSMutableIndexSet, NSNotificationCenter, and NSSimpleCString.


Autorelease pool debugging/performance DTrace probes added

Several DTrace probe points have been added for autorelease pool performance analysis and debugging using DTrace scripts:
provider Cocoa_Autorelease {
probe pool_push(unsigned long value);    // arg is a token representing pool
probe pool_pop_start(unsigned long value);    // arg is a token representing pool
probe pool_pop_end(unsigned long value);    // arg is a token representing pool
probe autorelease(unsigned long value);    // arg is object pointer
probe error_no_pool(unsigned long value);    // arg is object pointer
probe error_freed_object(unsigned long value);    // arg is object pointer
};
These are triggered at what should be the obvious points.


NSAutoreleasePool debugging helper methods deprecated

These methods in NSDebug.h in a category on NSAutoreleasePool have been deprecated:
+enableFreedObjectCheck:
+enableRelease:
+resetTotalAutoreleasedObjects
+totalAutoreleasedObjects
+autoreleasedObjectCount
+topAutoreleasePoolCount
+poolCountHighWaterMark
+setPoolCountHighWaterMark:
+poolCountHighWaterResolution
+setPoolCountHighWaterResolution:

This function no longer exists to set a breakpoint on:
_NSAutoreleaseHighWaterLog

There is no longer any direct way to do what these used to do.

These two breakpoint functions have been renamed:
_NSAutoreleaseNoPool to __NSAutoreleaseNoPool
_NSAutoreleaseFreedObject to __NSAutoreleaseFreedObject


System uptime

A new method, +systemUptime, has been added to NSProcessInfo (NSProcessInfo.h). This returns the amount of time the system has been awake since last restart.


New system clock change notification (Updated since November seed)

A new NSSystemClockDidChangeNotification notification is now available (NSDate.h), which is sent after the calendar clock of the machine changes (the clock used by NSDate, gettimeofday(), etc.).


NSJavaSetup.h removed

The NSJavaSetup.h header has been removed.


NSCondition availability

NSCondition is currently marked as available in Mac OS X 10.0 and later. However, there is a bug in the implementations on Mac OS X 10.0 - 10.4 that can make it not work properly in some usage patterns. So we will probably be marking it "available in 10.5 and later" at some point for the next release.


NSAssertionHandler changes

When compiling with a C99-compliant compiler, the NSAssert macro now accepts a variable number of arguments (including zero as before) for the description, and can be used instead of the argument-number-specific NSAssert1, NSAssert2, etc.

A new constant – NSAssertionHandlerKey – has been added which is the key in the thread dictionary of the per-thread assertion handler object.


NSObject changes

The -forwardingTargetForSelector: method is now properly declared on NSObject in NSObject.h.


New Block-based collection enumeration methods

New methods to enumerate collections have been added. These methods take Blocks which are invoked with each element in the collection (or subset thereof). These methods are currently not available to ObjC++, since Blocks are not yet available to C++.
NSArray:      -enumerateObjectsUsingBlock:, -enumerateObjectsWithOptions:usingBlock:, -enumerateObjectsAtIndexes:options:usingBlock:
NSDictionary: -enumerateKeysAndObjectsUsingBlock:, -enumerateKeysAndObjectsWithOptions:usingBlock:
NSSet: -enumerateObjectsUsingBlock:, -enumerateObjectsWithOptions:usingBlock:
NSIndexSet: -enumerateIndexesUsingBlock:, -enumerateIndexesWithOptions:usingBlock:, -enumerateIndexesInRange:options:usingBlock:
The type signatures for the Block arguments are:
NSArray:      void (^)(id obj, NSUInteger idx, BOOL *stop)
NSDictionary: void (^)(id key, id obj, BOOL *stop)
NSSet: void (^)(id obj, BOOL *stop)
NSIndexSet: void (^)(NSUInteger idx, BOOL *stop)
The 'stop' argument is an out-only argument, though not currently marked as such, and also, really, it is a pointer to a "volatile" BOOL. If you are going to use it at all, you should only ever set this boolean to YES, and never to NO, from within the Block.

See below for an explanation of the options flags.


New Block-based collection searching methods

New methods to test or search the elements of some collections have been added. These methods take Blocks which are invoked with each element in the collection (or subset thereof). The Block should return YES if the element matches the test being performed. These methods are currently not available to ObjC++, since Blocks are not yet available to C++.

These methods return the index of the first found matching object:
NSArray:     -indexOfObjectPassingTest:, -indexOfObjectWithOptions:passingTest:, -indexOfObjectAtIndexes:options:passingTest:
These methods return the first found matching index:
NSIndexSet:  -indexPassingTest:, -indexWithOptions:passingTest:, -indexInRange:options:passingTest:
These methods return an index set of all indexes of matching objects:
NSArray:     -indexesOfObjectsPassingTest:, -indexesOfObjectsWithOptions:passingTest:, -indexesOfObjectsAtIndexes:options:passingTest:
The type signatures for the Block arguments are the same as for the enumeration methods, for each class:
NSArray:     void (^)(id obj, NSUInteger idx, BOOL *stop)
NSIndexSet: void (^)(NSUInteger idx, BOOL *stop)
The 'stop' argument is an out-only argument, though not currently marked as such, and also, really, it is a pointer to a "volatile" BOOL. If you are going to use it at all, you should only ever set this boolean to YES, and never to NO, from within the Block.

See below for an explanation of the options flags.


New Block-based sorting methods

New methods to test the elements of some collections have been added. These methods take Blocks which are invoked with each element in the collection (or subset thereof). The Block is used to compare pairs of elements. These methods are currently not available to ObjC++, since Blocks are not yet available to C++.
NSArray:        -sortedArrayUsingComparator:, -sortedArrayWithOptions:usingComparator:
NSMutableArray: -sortUsingComparator:, -sortWithOptions:usingComparator:
NSDictionary: -keysSortedByValueUsingComparator:, -keysSortedByValueWithOptions:usingComparator:
The type signatures for the Block arguments are NSComparator:
NSComparisonResult (^)(id obj1, id obj2)
See below for an explanation of the options flags.


Options on the new Block-based collection enumeration, searching, and sorting methods

These options are available on the new Block-based collection enumeration and searching methods:

NSEnumerationConcurrent: invoke the Block on the selected elements concurrently; the order of invocation is nondeterministic and undefined; this flag is a hint and may be ignored by the implementation under some circumstances; the code of the Block must be safe against concurrent invocation

NSEnumerationReverse: invoke the Block on the selected elements in reverse of the natural order; available for NSArrays and NSIndexSets; undefined for NSDictionarys and NSSets, or when combined with the NSEnumerationConcurrent flag

These options are available on the new Block-based collection sorting methods:

NSSortConcurrent: invoke the Block concurrently on the pairs of elements to be compared; this flag is a hint and may be ignored by the implementation under some circumstances; the code of the Block must be safe against concurrent invocation

NSSortStable: use a stable sorting algorithm, so that equal elements remain in their original relative order; without this flag, it is undefined whether the sort algorithm will be stable or not


NSDiscardableContent protocol added

The NSDiscardableContent protocol has been added to NSObject.h. This protocol enables your objects to declare that their content may go away at any point, and allows users of your content to explicitly access the content in order to keep it around.


NSDiscardableContent-related NSObject method added

The -autoContentAccessingProxy method has been added in a category on NSObject. This method creates and returns an autoreleased proxy for the receiving object, if the receiver adopts the NSDiscardableContent protocol and still has undiscarded content. The proxy calls -beginContentAccess on the receiver to keep the content available as long as the proxy lives, and calls -endContentAccess when the proxy is deallocated (or finalized). The wrapper object is otherwise a subclass of NSProxy and forwards messages to the original receiver object as an NSProxy does. This method can be used to hide an NSDiscardableContent object's content volatility by creating an object that responds to the same messages but holds the contents of the original receiver available as long as the created proxy lives. Thus hidden, the NSDiscardableContent object (by way of the proxy) can be given out to unsuspecting recipients of the object who would otherwise not know they might have to call -beginContentAccess and -endContentAccess around particular usages (specific to each NSDiscardableContent object) of the NSDiscardableContent object.


NSCache class added

The NSCache class (NSCache.h) has been added to Foundation. This object acts somewhat like a mutable dictionary, except that objects can disappear out of it when there is memory pressure or in response to the sizing property hints. Objects put in a cache are retained by the cache (while they are in the cache).


Do not use NSCopyObject() (New since WWDC 2008)

This function is dangerous and very difficult to use correctly. It's use as part of -copyWithZone: by any class that can be subclassed, is highly error prone. This function is known to fail for objects with embedded retain count ivars, singletons, and C++ ivars, and other circumstances. Additionally, under GC or under ObjC 2.0, the zone is completely ignored.

Here is an implementation close to what is present in Mac OS X to illustrate:
id NSCopyObject(id object, NSUInteger extraBytes, NSZone *zone) {
if (object == nil) return nil;
id result = nil;
#if !__OBJC2__
if (!(objc_collecting_enabled() && auto_zone_size((malloc_zone_t *)NSDefaultMallocZone(), object))) {
if (!zone) zone = NSDefaultMallocZone();
result = object_copyFromZone(object, extraBytes, (void *)zone);
} else
#endif
{ // ignore zone completely
result = class_createInstance([object class], extraBytes);
NSUInteger size = class_getInstanceSize([object class]) + extraBytes;
objc_memmove_collectable(result, object, size);
}
return result;
}
Obviously, the objc_memmove_collectable() (essentially, memmove()) is not the right thing for C++ ivars, and object_copyFromZone() is known not to work for C++ ivars as well. More cautions on using NSCopyObject() can be found here:
http://developer.apple.com/documentation/LegacyTechnologies/WebObjects/WebObjects_3.5/Reference/Frameworks/ObjC/Foundation/Protocols/NSCopying/Description.html

NSCopyObject() is likely to be deprecated after Mac OS X 10.6.


NSOperation, NSOperationQueue changes (New since WWDC 2008)

There are several new methods on NSOperation:
- (void (^)(void))completionBlock;
- (void)setCompletionBlock:(void (^)(void))block;
You can set a Block to be invoked when the NSOperation is finished. The execution context of this Block is undefined, and the Block should shunt things appropriately if this or that thing it does needs to be done in a particular context.
- (void)waitUntilFinished;
Blocks execution of the current thread until after the receiving operation has finished. Use this method with care, as it can be an easy way to deadlock your applications.
- (double)threadPriority;
- (void)setThreadPriority:(double)p;
Specifies what the priority of the thread should be while executing -main. Only applies to non-concurrent (isConcurrent returns NO) operations. The priority is changed on a best-effort basis and can't be guaranteed.


There are several new methods on NSOperationQueue:
- (void)addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait;
Bulk adder, with option of waiting each all of those operations has finished. The thread is blocked during the wait. Adding operations with -addOperation: is also much faster than in 10.5.
- (NSUInteger)operationCount;
A faster way to get the current number of operations in the queue, without getting the entire array of operations. Of course, this information may be out-of-date by the time you get and use the return value (just as the operations array can be out-of-date), so it should only be used for approximate guidance.
- (void)setName:(NSString *)n;
- (NSString *)name;
NSOperationQueues can now be named, and some tools may be able to see this name.
+ (id)currentQueue;
The currentQueue is the one running the current operation's code -- if the code being executed is being done so in the context of an NSOperation, of course. The return value is often nil.
+ (id)mainQueue;
This method returns a queue that represents the main dispatch queue. This is a serial (one thing at a time) queue and only serviced on the main thread. It is never serviced re-entrantly.



New class NSBlockOperation (New since WWDC 2008)

This is a subclass of NSOperation to which Blocks can be added, and the object will execute the Blocks as its work. If multiple Blocks are added (-addExecutionBlock:), they are executed concurrently. The operation will become Finished when all the Blocks are done executing. This may be a convenient way to get concurrent fan-out in some cases without having to create multiple NSOperations.


NSOperationQueue and Concurrent Operations and the "Current Thread" in 10.5 (New since WWDC 2009)

In attempting to explain concurrent NSOperations in the 10.5 documentation, the documentation contained this comment: "For a concurrent operation, the queue simply calls the object’s start method on the current thread."  Some people have taken this to be a defined behavior of the NSOperationQueue API, but as the documentation did not say or make any committments about what the "current thread" was, this was not information that could be usefully acted or relied upon.

What the documentation was describing was a 4-line sequence like this in the 10.5.x NSOperationQueue implementation:
   if ([op isConcurrent]) {
      [op start];
   } else {
     [NSThread detachNewThreadSelector:@selector(start) toTarget:op withObject:nil];
   }
and from that point of view the documentation was literally correct.  However, one step farther out the question becomes: "on what thread is that code invoked?"  Or similarly, "when is that code invoked?" Without that information, the fact that -start was "called on the current thread" cannot obviously and seriously be relied upon to achieve any particular effect.

In 10.5 what actually happened was that that chunk of code was run whenever an NSOperation finished, on whatever thread posted the isFinished KVO notification for that operation, which the operation queue would listen for and react to by starting the next operation.  The code was also invoked at other times when it was determined that "capacity exists" and "there is some work to do" (such as after an addOperation:) and an operation to run had been chosen from the queue.  [Note that although an addOperation: on some thread might cause another operation to be run, since NSOperationQueues are not FIFO queues it would not necessarily be that specific new operation which would be chosen.]  So, the "current thread" could be potentially any thread, including ones which would shortly thereafter terminate.

These comments and some example code have been removed from the 10.6 documentation.



Hashing-based collections changes (New since WWDC 2008)

The CoreFoundation and Foundation framework-provided implementations of hashing-based collections such as dictionaries have changed how they store elements, so elements may be retrieved in a different order than in previous releases. The order of elements in hashing-based collections is undefined and can change at any time, so developers must never rely on the order that elements are enumerated, or returned from a function like CFDictionaryGetKeysAndValues(). This is true even for cases where a developer may be trying to manipulate the hash codes of the objects in order to achieve some particular ordering.

The hashing algorithm is also different, so very carefully constructed -hash methods to produce perfect hash functions for a given set of objects may cause more collisions than in Leopard. On the other hand, the algorithm is more robust against middling or mediocre hash functions, though also somewhat slower in terms of cpu usage.

The maximum load factor of hashing collections now varies with the size of the collection, but for medium and large collections (say, over 100 elements, though not necessarily that specific number) is around 62% versus the 75% of Leopard. Other changes have made hashing collections grow more slowly than previously, as a memory-saving measure, which may produce more growth-induced rehashes than in Leopard (mainly impacts cpu time).



NSNotificationCenter new API (New since November seed)

This method has been added to NSNotificationCenter:
- (id)addObserverForName:(NSString *)name object:(id)obj queue:(NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *))block;
You can use it to specify a block to handle notifications, instead of the traditional target object and selector. An object to act as the observer – of unspecified type, though it will respond to methods in the NSObject protocol – is created for you and returned. You use -removeObserver: with this returned object as the parameter, to cancel a registration. The system maintains a retain on this object (until it is removed). Under GC, as with observers registered with the old addObserver:... method, the system does not keep a reference to those observers, and registrations are automatically cleaned up when an observer is collected.  So under GC, you need to hang-on to the returned observer object somewhere (which is probably the case if you intend to explicitly call removeObserver: on it), as long as you want the notification registration to remain.

This new API also accomplishes 3 other things:
- the unregistration is exact; this registration does not suffer from the ambiguity of -removeObserver:name:object: as to which registration will be removed
- the execution context of the notification handler can be specified, at least to the degree of an NSOperationQueue; if the queue parameter is non-nil, the notification is handled in the context of that operation queue. If the queue parameter is nil, the block is invoked as traditionally, in the context of the posting thread.
- the execution of observer handlers added this way is performed concurrently with other observers' notification handlers. Execution order of notification handlers has always been unpredictable, and observers should not depend on another observer handling a notification before or after it. The concurrency may make such issues more apparent. Note that although observers are concurrently invoked, posting still waits until all observers have finished executing their handlers.


Using NSNotificationQueue Warning (New since WWDC 2009)

NSNotificationQueue is an API and mechanism related to run loops (NSRunLoop), and the running of run loops.  In particular, posting of notifications via the notification queue is driven by the running of its associated run loop.  However, there is no definition for what run loop a notification queue uses, and there is no way for a client to configure that.  In fact, any given notification queue might be "tickled" into posting by nearly any run loop and different ones at different times (and given that enqueued notifications are also mode-specific, what mode(s) the run loop(s) are running in any any given time also come into play).  Further, although each notification queue is "thread-specific" (see the +defaultQueue documentation), there has never been any relationship between that thread and the run loop used by a notification queue.  This is all more and more problematic as more and more things move to happening on different and new threads.

The practical upshot is:
- Notifications posted through a queue might not be posted in any particular "timely" fashion;
- Notifications posted through a queue might not ever be posted (the run loop of the thread that the queue chose to ask to poke it might not be run again; for example, the thread of that run loop might exit and the notification queue discarded);
- Notifications can be posted by any given queue on a different thread than the thread the queue is the default queue for (when a queue is a default queue for some thread);
- Notifications can be posted by any given queue on different threads over time;
- There is no necessary/guaranteed relationship between the thread(s) on which notifications are enqueued and those on which the notifications eventually get posted (delivered) for any notification queue

This is true for all releases of Mac OS X.  Foundation and AppKit do not use NSNotificationQueue themselves, partly for these reasons.


Concurrency, GCD, and Run Loop Cautions (New since November seed)

Many Foundation and AppKit APIs are still run loop-based. Two examples are NSTask and NSFileHandle. These APIs have no queue-targetting or completion-block-taking APIs yet. To get the completion notifications (e.g., about task termination or a read in background finishing), the run loop of the thread which started the asynchronous operation (e.g., launched the task or started the background read) must still be run, as historically, at least until that notification is delivered.

If you are switching code to NSOperation or GCD, or in general when code is moved from one execution context where it is nice and comfortable to another execution context, there can be indirect effects. Of course, if you are introducing concurrency or threads, the code may need to be audited for concurrency safety and adjusted. If the code was depending on per-thread data existing (perhaps something else created it), that per-thread data may not exist. Or, the code may have been putting sources or timers in the current thread's run loop, and relying on something else to run the run loop, which may not happen in the new execution environment. Relatedly, but conversely, if some code was putting sources in the current run loop, and that code moves elsewhere, the current run loop of the original thread may no longer have anything in it, and so other code which attempts to run that run loop may just end up spinning or doing nothing. And certainly if the running of that run loop was supposed to service something that would cause the running of that run loop to stop, those conditions may get changed any more which may mean a run loop running loop may not terminate, and spin forever.



NSIndexPath changes (New since WWDC 2008)

On Pre-Leopard systems, NSIndexPath's -indexPathByRemovingLastIndex would return nil if the receiver had a length of 1. On Leopard and newer systems, this method will return an empty indexPath instead and will never return nil.


NSAttributedString

NSAttributedString now has two methods to allow enumerations using blocks.
- (void)enumerateAttributesInRange:(NSRange)enumerationRange
options:(NSAttributedStringEnumerationOptions)opts
usingBlock:(void (^)(NSDictionary *attrs, NSRange range, inout BOOL *stop))block;
This method will execute the provided block with every attribute run in enumerationRange, passing it the attributes dictionary and the range over which is applies.

Ranges are by default the longest effective range, clipped to enumerationRange. If NSAttributedStringEnumerationLongestEffectiveRangeNotRequired option is supplied, then the longest effective range computation is not performed; the blocks may be invoked with consecutive attribute runs that have the same value.

The block can stop the enumeration by setting *stop = YES; it shouldn't touch *stop otherwise.

If this method is sent to an instance of NSMutableAttributedString, mutation (deletion, addition, or change) is allowed, as long as it is within the range provided to the block; after a mutation, the enumeration continues with the range immediately following the processed range, after the length of the processed range is adjusted for the mutation. (The enumerator basically assumes any change in length occurs in the specified range.) For example, if the block is called with a range starting at location N, and the block deletes all the characters in the supplied range, the next call will also pass N as the index of the range.
- (void)enumerateAttribute:(NSString *)attrName
inRange:(NSRange)enumerationRange
options:(NSAttributedStringEnumerationOptions)opts
usingBlock:(void (^)(id value, NSRange range, inout BOOL *stop))block;
This method is similar to the above, but enumeration takes place on a single attribute.


NSString (Updated since November seed)

NSString now has API for enumerating a variety of substring types using blocks:
- (void)enumerateSubstringsInRange:(NSRange)range
options:(NSStringEnumerationOptions)options
usingBlock:(void (^)(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop))block;
This method enumerates the substrings of the specified type (lines, words, sentences, etc) in the specified range of the receiver.

The options argument specifies the substring type to enumerate, as well as the following:
NSStringEnumerationSubstringNotRequired can be used as a way to indicate that the block does not need substring, in which case nil will be passed. This is simply a performance shortcut.
NSStringEnumerationReverse causes enumeration to occur from the end of the specified range to the start.
NSStringEnumerationLocalized causes the enumeration to occur using user's default locale.  This will never make a difference in line, paragraph, or composed character sequence enumeration, but it may for words or sentences.

In the block that is executed, substring is the enumerated string, substringRange is the range of the enumerated string in the receiver, and enclosingRange is the range that includes the substring as well as any separator/filler characters that follow.

For instance, for lines, enclosingRange will contain the line terminators. The enclosingRange for the first string enumerated will also contain any characters that occur before the string. Consecutive enclosing ranges are guaranteed not to overlap, and every single character in the enumerated range will be included in one and only one enclosing range.

The block can stop the enumeration by setting *stop = YES; it shouldn't touch *stop otherwise.

If this method is sent to an instance of NSMutableString, mutation (deletion, addition, or change) is allowed, as long as it is within enclosingRange. After a mutation, the enumeration continues with the range immediately following the processed range, after the length of the processed range is adjusted for the mutation. (The enumerator basically assumes any change in length occurs in the specified range.)   For example, if the block is called with a range starting at location N, and the block deletes all the characters in the supplied range, the next call will also pass N as the index of the range.  Note that this is the case even if mutation of the previous range changes the string in such a way that the following substring would have extended to include the already enumerated range. (For example, if the string "Hello World" is enumerated via words, and the block changes "Hello " to "Hello", thus forming "HelloWorld", the next enumeration will return "World" rather than "HelloWorld".

This next method is a convenience method to enumerate all the lines in a string.  The passed in line contains just the contents of the line, without the line terminators:
- (void)enumerateLinesUsingBlock:(void (^)(NSString *line, BOOL *stop))block;
As of WWDC 2009, word and sentence enumeration are implemented, but word enumeration is not yet correct in Japanese, Chinese, and Thai.


NSString (New Since WWDC2008)

NSString has a bunch of convenience methods for comparison, but none correspond directly to the way file names are sorted in the system by Finder or the open panel.   This comparison is possible in Leopard with:
return [str compare:otherStr
            options:NSCaseInsensitiveSearch|NSNumericSearch|NSWidthInsensitiveSearch|NSForcedOrderingSearch
           range:NSMakeRange(0, [str length])
           locale:[NSLocale currentLocale]];
but SnowLeopard adds a new API for this:
- (NSComparisonResult)localizedStandardCompare:(NSString *)string;
This method should be used whenever file names or other strings are presented in lists and tables where Finder-like sorting is appropriate.  The exact behavior and implementation of this method may be tweaked in future releases, and will be different under different localizations, so clients should not depend on the exact sorting order of the strings, and should not assume the implementation will remain as shown above.

The methods lengthOfBytesUsingEncoding: and maximumLengthOfBytesUsingEncoding: now return 0 if the amount of memory required for storing the results of the encoding conversion would exceed NSIntegerMax. Note that the former would already return 0 for any conversion errors.

The methods substringWithRange:, getLineStart:end:contentsEnd:forRange:, rangeOfString:, rangeOfCharacterFromSet:, and variants (more specialized forms) will now detect all invalid ranges (including those with negative lengths). For apps linked against SnowLeopard, this error will cause an exception; for apps linked against earlier releases, this error causes a warning, which is displayed just once per app execution.

The methods -UTF8String and cStringUsingEncoding: are now declared as __strong, which means they return pointers that are safe to keep around when running with garbage collection.

Foundation APIs which take string format arguments (APIs such as initWithFormat:, NSLog(), etc) are now decorated with attributes which allow the compiler to generate warnings on potentially unsafe usages. This currently includes usage such as:
NSString *str = ...;
NSString *formattedStr = [[NSString alloc] initWithFormat:str];
where the format is not a constant and there are no arguments. In a case like above, the call to initWithFormat: is unnecessary, so to avoid warnings, just drop the call. In a case like NSLog(str), you can instead use NSLog(@"%@", str).


NSData (New Since WWDC2008)

The following enum values have been renamed as shown:
    NSMappedRead   -> NSDataReadingMapped
NSUncachedRead -> NSDataReadingUncached
NSAtomicWrite -> NSDataWritingAtomic
The old names are still available but deprecated and will be removed in a future release.


NSError

NSError has a new method and key to enable displaying a help button to accompany the error when it's displayed to the user:
NSString *const NSHelpAnchorErrorKey;
- (NSString *)helpAnchor;
If -[NSError helpAnchor] returns a non-nil value for an error being used with +[NSAlert alertWithError:], the alert panel will include a help anchor button with that value. The various presentError: variants in the kit go through the NSAlert method and will thus automatically generate a help button.

The easy way to get a value set for -helpAnchor is to specify it as the value of NSHelpAnchorErrorKey in the NSError's userInfo dictionary; or the method can be overridden.

Although this functionality is publicized in 10.6, it is available back to 10.4.

We have also added a new error code, NSFileWriteVolumeReadOnlyError, to represent the error attempting to write to a read only volume.

Error messages for validation errors in NSNumberFormatter have been improved; instead of "Formatting error" the messages will now try to indicate the invalid value and reason for validation failure. Note that NSNumberFormatter uses NSFormattingError for indicating validation errors; this value is a bit unfortunately named for now, and this could be addressed in the future.


NSComparator warnings note (New since November seed)

In trying to use NSComparator blocks like so:
  [myArray sortUsingComparator:^(id obj1, id obj2) {
return ([obj1 doubleValue] < [obj2 doubleValue]) ? NSOrderedAscending : NSOrderedDescending;
}];
You may get an error from the compiler:
  error: incompatible block pointer types initializing ‘int (^)(struct objc_object *, struct objc_object *)’, expected ‘NSComparator’
This is because the block thinks its return value is int. One solution is to cast the return values:
  [myArray sortUsingComparator:^(id obj1, id obj2) {
return ([obj1 doubleValue] < [obj2 doubleValue]) ? (NSComparisonResult)NSOrderedAscending : (NSComparisonResult)NSOrderedDescending;
}];
A better solution is to declare the block as returning NSComparisonResult:
  [myArray sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return ([obj1 doubleValue] < [obj2 doubleValue]) ? NSOrderedAscending : NSOrderedDescending;
}];

Collection comparisons with isEqual: vs isEqualTo<collection>:

In Leopard and earlier releases, isEqual: and isEqualToArray: (or Dictionary/Set) went through different code paths, which could sometimes give different results. In SnowLeopard, in apps linked against SnowLeopard, isEqual: now goes through the corresponding isEqualTo... methods for the three collection types. This should cause these methods to give consistent results. One noteworthy change here is that the two numbers [NSNumber numberWithInteger:1] and [NSNumber numberWithBool:YES] (or numbers created with 0 and NO) will now compare equal when in collections (just like they do when compared with -[NSNumber isEqual:]).


Foundation API not available in iOS 2.0

The Mac OS X APIs in these headers are not available in iOS 2.0:
NSAffineTransform.h, NSAppleEventDescriptor.h, NSAppleEventManager.h, NSAppleScript.h, NSArchiver.h, NSAttributedString.h, NSCache.h, NSCalendarDate.h, NSClassDescription.h, NSComparisonPredicate.h, NSCompoundPredicate.h, NSConnection.h, NSDistantObject.h, NSDistributedLock.h, NSDistributedNotificationCenter.h, NSExpression.h, NSGarbageCollector.h, NSGeometry.h, NSHFSFileTypes.h, NSHashTable.h, NSHost.h, NSMapTable.h, NSMetadata.h, NSObjectScripting.h, NSPointerArray.h, NSPointerFunctions.h, NSPortCoder.h, NSPortMessage.h, NSPortNameServer.h, NSPredicate.h, NSProtocolChecker.h, NSScriptClassDescription.h, NSScriptCoercionHandler.h, NSScriptCommand.h, NSScriptCommandDescription.h, NSScriptExecutionContext.h, NSScriptKeyValueCoding.h, NSScriptObjectSpecifiers.h, NSScriptStandardSuiteCommands.h, NSScriptSuiteRegistry.h, NSScriptWhoseTests.h, NSSpellServer.h, NSTask.h, NSURLDownload.h, NSURLHandle.h, NSUndoManager.h, NSValueTransformer.h, NSXMLDTD.h, NSXMLDTDNode.h, NSXMLDocument.h, NSXMLElement.h, NSXMLNode.h, NSXMLNodeOptions.h

Various other APIs which are either related to (or use types defined by) the above, or which are deprecated as of 10.5, are also unavailable.

Additionally, these APIs in the available headers are not available:
- The garbage collector-related allocation APIs (NSAllocateCollectable(), NSReallocateCollectable(), and their option flags) in NSZone.h
- The NSCoder -encodePropertyList: and -decodePropertyList methods (just use -encodeObject: and -decodeObject)
- 10.0-behavior-specific methods on NSDateFormatter and NSNumberFormatter

Otherwise, iOS 2.0 contains a Foundation API matching that in Mac OS X 10.5.


Foundation API not available in iOS 3.0

The Mac OS X APIs in these headers are not available in iOS 3.0:
NSAffineTransform.h, NSAppleEventDescriptor.h, NSAppleEventManager.h, NSAppleScript.h, NSArchiver.h, NSAttributedString.h, NSCache.h, NSCalendarDate.h, NSClassDescription.h, NSConnection.h, NSDistantObject.h, NSDistributedLock.h, NSDistributedNotificationCenter.h, NSGarbageCollector.h, NSGeometry.h, NSHFSFileTypes.h, NSHashTable.h, NSHost.h, NSMapTable.h, NSMetadata.h, NSObjectScripting.h, NSPointerArray.h, NSPointerFunctions.h, NSPortCoder.h, NSPortMessage.h, NSPortNameServer.h, NSProtocolChecker.h, NSScriptClassDescription.h, NSScriptCoercionHandler.h, NSScriptCommand.h, NSScriptCommandDescription.h, NSScriptExecutionContext.h, NSScriptKeyValueCoding.h, NSScriptObjectSpecifiers.h, NSScriptStandardSuiteCommands.h, NSScriptSuiteRegistry.h, NSScriptWhoseTests.h, NSSpellServer.h, NSTask.h, NSURLDownload.h, NSURLHandle.h, NSXMLDTD.h, NSXMLDTDNode.h, NSXMLDocument.h, NSXMLElement.h, NSXMLNode.h, NSXMLNodeOptions.h

Various other APIs which are either related to (or use types defined by) the above, or which are deprecated as of 10.5, are also unavailable.

Additionally, these APIs in the available headers are not available:
- The garbage collector-related allocation APIs (NSAllocateCollectable(), NSReallocateCollectable(), and their option flags) in NSZone.h
- The NSCoder -encodePropertyList: and -decodePropertyList methods (just use -encodeObject: and -decodeObject)
- 10.0-behavior-specific methods on NSDateFormatter and NSNumberFormatter

Otherwise, iOS 3.0 contains a Foundation API matching that in Mac OS X 10.5.