Re: NsDictionary setValue vs setObject

My reading is that setObject:forKey: is the method which does the business of either adding a key-value pair to a mutable dictionary or changing the value associated with a key. The only limitation set on the 'key' parameter is that it must be a copiable object — presumably so that the key in the dictionary can be made a separate object from the parameter itself. But I can't immediately see why anyone would want to use anything other than text. Only dictionaries whose keys are all text can be coerced to AppleScript records.

Dictionaries, arrays, and sets aren't allowed to contain nil (usually represented by 'missing value' in ASObjC), so the 'object' parameter mustn't be 'missing value'. If it is, setObject:forKey: throws an error.

If a dictionary or an array is derived from an AppleScript record or list already containing 'missing value' values, the 'missing values' are represented in the result as instances of NSNull, for which there's no equivalent in AppleScript. Coercing the dictionary or array back to record or list produces 'missing values' from the NSNull instances. So if you need to set a 'missing value' equivalent in a dictionary, it has to be passed as an NSNull instance:

Applescript:

use AppleScript version "2.4"-- Yosemite (10.10) or lateruse framework "Foundation"
use scripting additions

set dict to current application's class "NSMutableDictionary"'s dictionaryWithDictionary:({a:"aardvark", b:"banana"})

set |null| to current application's class "NSNull"'s |null|() -- No connection with the unofficial AS keyword 'null'.tell dict to setObject:(|null|) forKey:("b")tell dict to setObject:(|null|) forKey:("c")return dict as record -- {a:"aardvark", b:missing value, c:missing value}

setValue:forKey: is three system versions younger than setObject:forKey: and is essentially a "convenience" or "smart" version of it. If it's used to add a key-value pair or change a value in a mutable dictionary, it calls setObject:forKey: to do the work. The difference is that if the 'value' parameter is nil (or AppleScript's 'missing value'), removeObjectForKey: is invoked instead to remove the key and its current value if they exist:

Applescript:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set dict to current application's class "NSMutableDictionary"'s dictionaryWithDictionary:({a:"aardvark", b:"banana"})

Re: NsDictionary setValue vs setObject

But I can't immediately see why anyone would want to use anything other than text.

In ASObjC, no, but in Objective-C there can be times when it makes sense to use other classes.

setValue:forKey: is three system versions younger than setObject:forKey:

setValue:forKey: is actually defined in NSObject (twice!), so it's inherited, but the collection classes override it with their own implementations. The setValue:forKey: method, plus valueForKey: are the basis of Key Value Coding, which is (partly) about being able to use strings for method calls.