1 2 /* Interface for NSKeyValueCoding for GNUStep 3 Copyright (C) 2000 Free Software Foundation, Inc. 4 5 Written by: Richard Frith-Macdonald <rfm@gnu.org> 6 Date: 2000 7 8 This file is part of the GNUstep Base Library. 9 10 This library is free software; you can redistribute it and/or 11 modify it under the terms of the GNU Lesser General Public 12 License as published by the Free Software Foundation; either 13 version 2 of the License, or (at your option) any later version. 14 15 This library is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 Lesser General Public License for more details. 19 20 You should have received a copy of the GNU Lesser General Public 21 License along with this library; if not, write to the Free 22 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 23 Boston, MA 02110 USA. 24 */ 25 26 #ifndef __NSKeyValueCoding_h_GNUSTEP_BASE_INCLUDE 27 #define __NSKeyValueCoding_h_GNUSTEP_BASE_INCLUDE 28 #import <GNUstepBase/GSVersionMacros.h> 29 30 #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) 31 32 #import <Foundation/NSObject.h> 33 34 #if defined(__cplusplus) 35 extern "C" { 36 #endif 37 38 @class NSArray; 39 @class NSMutableArray; 40 @class NSSet; 41 @class NSMutableSet; 42 @class NSDictionary; 43 @class NSError; 44 @class NSString; 45 46 /** An exception for an unknown key in [NSObject(NSKeyValueCoding)]. */ 47 GS_EXPORT NSString* const NSUndefinedKeyException; 48 49 /** 50 * <p>This describes an informal protocol for <em>key-value coding</em>, a 51 * mechanism whereby the fields of an object may be accessed and set using 52 * generic methods in conjunction with string keys rather than field-specific 53 * methods. Key-based access loses compile-time validity checking, but can be 54 * convenient in certain kinds of situations.</p> 55 * 56 * <p>The basic methods are implemented as a category of the [NSObject] class, 57 * but other classes override those default implementations to perform more 58 * specific operations.</p> 59 */ 60 @interface NSObject (NSKeyValueCoding) 61 62 /** 63 * Controls whether the NSKeyValueCoding methods may attempt to 64 * access instance variables directly. 65 * NSObject's implementation returns YES. 66 */ 67 + (BOOL) accessInstanceVariablesDirectly; 68 69 /** 70 * Controls whether -storedValueForKey: and -takeStoredValue:forKey: may use 71 * the stored accessor mechanism. If not the calls get redirected to 72 * -valueForKey: and -takeValue:forKey: effectively changing the search order 73 * of private/public accessor methods and instance variables. 74 * NSObject's implementation returns YES. 75 */ 76 + (BOOL) useStoredAccessor; 77 78 /** 79 * Returns a dictionary built from values obtained for the specified keys.<br /> 80 * By default this is derived by calling -valueForKey: for each key. 81 * Any nil values obtained are represented by an [NSNull] instance. 82 */ 83 - (NSDictionary*) dictionaryWithValuesForKeys: (NSArray*)keys; 84 85 /** 86 * Deprecated ... use -valueForUndefinedKey: instead. 87 */ 88 - (id) handleQueryWithUnboundKey: (NSString*)aKey; 89 90 /** 91 * Deprecated, use -setValue:forUndefinedKey: instead. 92 */ 93 - (void) handleTakeValue: (id)anObject forUnboundKey: (NSString*)aKey; 94 95 /** 96 * Returns a mutable array value for a given key. This method: 97 * <list> 98 * <item>Searches the receiver for methods matching the patterns 99 * insertObject:in<Key>AtIndex: and 100 * removeObjectFrom<Key>AtIndex:. If both 101 * methods are found, each message sent to the proxy array will result in the 102 * invocation of one or more of these methods. If 103 * replaceObjectIn<Key>AtIndex:withObject: 104 * is also found in the receiver it 105 * will be used when appropriate for better performance.</item> 106 * <item>If the set of methods is not found, searches the receiver for a the 107 * method set<Key>:. Each message sent to the proxy array will result in 108 * the invocation of set<Key>:</item> 109 * <item>If the previous do not match, and accessInstanceVariablesDirectly 110 * returns YES, searches for an instance variable matching _<key> or 111 * <key> (in that order). If the instance variable is found, 112 * messages sent 113 * to the proxy object will be forwarded to the instance variable.</item> 114 * <item>If none of the previous are found, raises an NSUndefinedKeyException 115 * </item> 116 * </list> 117 */ 118 - (NSMutableArray*) mutableArrayValueForKey: (NSString*)aKey; 119 120 /** 121 * Returns a mutable array value for the given key path. 122 */ 123 - (NSMutableArray*) mutableArrayValueForKeyPath: (NSString*)aKey; 124 125 /** 126 * Returns a mutable set value for a given key. This method: 127 * <list> 128 * <item>Searches the receiver for methods matching the patterns 129 * add<Key>Object:, remove<Key>Object:, 130 * add<Key>:, and remove<Key>:, which 131 * correspond to the NSMutableSet methods addObject:, removeObject:, 132 * unionSet:, and minusSet:, respectively. If at least one addition 133 * and one removal method are found, each message sent to the proxy set 134 * will result in the invocation of one or more of these methods. If 135 * intersect<Key>: or set<Key>: 136 * is also found in the receiver, the method(s) 137 * will be used when appropriate for better performance.</item> 138 * <item>If the set of methods is not found, searches the receiver for a the 139 * method set<Key>:. Each message sent to the proxy set will result in 140 * the invocation of set<Key>:</item> 141 * <item>If the previous do not match, and accessInstanceVariablesDirectly 142 * returns YES, searches for an instance variable matching _<key> or 143 * <key> (in that order). If the instance variable is found, 144 * messages sent 145 * to the proxy object will be forwarded to the instance variable.</item> 146 * <item>If none of the previous are found, raises an NSUndefinedKeyException 147 * </item> 148 * </list> 149 */ 150 - (NSMutableSet*) mutableSetValueForKey: (NSString *)aKey; 151 152 /** 153 * Returns a mutable set value for the given key path. 154 */ 155 - (NSMutableSet*) mutableSetValueForKeyPath: (NSString*)aKey; 156 157 /** 158 * This method is invoked by the NSKeyValueCoding mechanism when an attempt 159 * is made to set an null value for a scalar attribute. This implementation 160 * raises an NSInvalidArgument exception. Subclasses my override this method 161 * to do custom handling. (E.g. setting the value to the equivalent of 0.) 162 */ 163 - (void) setNilValueForKey: (NSString*)aKey; 164 165 /** 166 * Sets the value if the attribute associated with the key in the receiver. 167 * The object is converted to a scalar attribute where applicable (and 168 * -setNilValueForKey: is called if a nil value is supplied). 169 * Tries to use a standard accessor of the form setKey: where 'Key' is the 170 * supplied argument with the first letter converted to uppercase.<br /> 171 * If the receiver's class allows +accessInstanceVariablesDirectly 172 * it continues with instance variables: 173 * <list> 174 * <item>_key</item> 175 * <item>_isKey</item> 176 * <item>key</item> 177 * <item>isKey</item> 178 * </list> 179 * Invokes -setValue:forUndefinedKey: if no accessor mechanism can be found 180 * and raises NSInvalidArgumentException if the accessor method doesn't take 181 * exactly one argument or the type is unsupported (e.g. structs). 182 * If the receiver expects a scalar value and the value supplied 183 * is the NSNull instance or nil, this method invokes 184 * -setNilValueForKey: . 185 */ 186 - (void) setValue: (id)anObject forKey: (NSString*)aKey; 187 188 /** 189 * Retrieves the object returned by invoking -valueForKey: 190 * on the receiver with the first key component supplied by the key path. 191 * Then invokes -setValue:forKeyPath: recursively on the 192 * returned object with rest of the key path. 193 * The key components are delimited by '.'. 194 * If the key path doesn't contain any '.', this method simply 195 * invokes -setValue:forKey:. 196 */ 197 - (void) setValue: (id)anObject forKeyPath: (NSString*)aKey; 198 199 /** 200 * Invoked when -setValue:forKey: / -takeStoredValue:forKey: are called with 201 * a key which can't be associated with an accessor method or instance 202 * variable. Subclasses may override this method to add custom handling. 203 * NSObject raises an NSUndefinedKeyException, with a userInfo dictionary 204 * containing NSTargetObjectUserInfoKey with the receiver an 205 * NSUnknownUserInfoKey with the supplied key entries.<br /> 206 * Called when the key passed to -setValue:forKey: cannot be used. 207 */ 208 - (void) setValue: (id)anObject forUndefinedKey: (NSString*)aKey; 209 210 /** 211 * Uses -setValue:forKey: to place the values from aDictionary in the 212 * receiver. 213 */ 214 - (void) setValuesForKeysWithDictionary: (NSDictionary*)aDictionary; 215 216 /** 217 * Returns the value associated with the supplied key as an object. 218 * Scalar attributes are converted to corresponding objects. 219 * Uses private accessors in favor of the public ones, if the receiver's 220 * class allows +useStoredAccessor. Otherwise this method invokes 221 * -valueForKey:. 222 * The search order is:<br/> 223 * Private accessor methods: 224 * <list> 225 * <item>_getKey</item> 226 * <item>_key</item> 227 * </list> 228 * If the receiver's class allows +accessInstanceVariablesDirectly 229 * it continues with instance variables: 230 * <list> 231 * <item>_key</item> 232 * <item>key</item> 233 * </list> 234 * Public accessor methods: 235 * <list> 236 * <item>getKey</item> 237 * <item>key</item> 238 * </list> 239 * Invokes -handleTakeValue:forUnboundKey: if no accessor mechanism can be 240 * found and raises NSInvalidArgumentException if the accessor method takes 241 * takes any arguments or the type is unsupported (e.g. structs). 242 */ 243 - (id) storedValueForKey: (NSString*)aKey; 244 245 /** 246 * Sets the value associated with the supplied in the receiver. 247 * The object is converted to the scalar attribute where applicable. 248 * Uses the private accessors in favor of the public ones, if the 249 * receiver's class allows +useStoredAccessor . 250 * Otherwise this method invokes -takeValue:forKey: . 251 * The search order is:<br/> 252 * Private accessor methods: 253 * <list> 254 * <item>_setKey:</item> 255 * </list> 256 * If the receiver's class allows accessInstanceVariablesDirectly 257 * it continues with instance variables: 258 * <list> 259 * <item>_key</item> 260 * <item>key</item> 261 * </list> 262 * Public accessor methods: 263 * <list> 264 * <item>setKey:</item> 265 * </list> 266 * Invokes -handleTakeValue:forUnboundKey: 267 * if no accessor mechanism can be found 268 * and raises NSInvalidArgumentException if the accessor method doesn't take 269 * exactly one argument or the type is unsupported (e.g. structs). 270 * If the receiver expects a scalar value and the value supplied 271 * is the NSNull instance or nil, this method invokes 272 * -unableToSetNilForKey: . 273 */ 274 - (void) takeStoredValue: (id)anObject forKey: (NSString*)aKey; 275 276 /** 277 * Iterates over the dictionary invoking -takeStoredValue:forKey: 278 * on the receiver for each key-value pair, converting NSNull to nil. 279 */ 280 - (void) takeStoredValuesFromDictionary: (NSDictionary*)aDictionary; 281 282 /** 283 * Sets the value if the attribute associated with the key in the receiver. 284 * The object is converted to a scalar attribute where applicable. 285 * Uses the public accessors in favor of the private ones. 286 * The search order is:<br/> 287 * Accessor methods: 288 * <list> 289 * <item>setKey:</item> 290 * <item>_setKey:</item> 291 * </list> 292 * If the receiver's class allows +accessInstanceVariablesDirectly 293 * it continues with instance variables: 294 * <list> 295 * <item>key</item> 296 * <item>_key</item> 297 * </list> 298 * Invokes -handleTakeValue:forUnboundKey: 299 * if no accessor mechanism can be found 300 * and raises NSInvalidArgumentException if the accessor method doesn't take 301 * exactly one argument or the type is unsupported (e.g. structs). 302 * If the receiver expects a scalar value and the value supplied 303 * is the NSNull instance or nil, this method invokes 304 * -unableToSetNilForKey: .<br /> 305 * Deprecated ... use -setValue:forKey: instead. 306 */ 307 - (void) takeValue: (id)anObject forKey: (NSString*)aKey; 308 309 /** 310 * Retrieves the object returned by invoking -valueForKey: 311 * on the receiver with the first key component supplied by the key path. 312 * Then invokes -takeValue:forKeyPath: recursively on the 313 * returned object with rest of the key path. 314 * The key components are delimited by '.'. 315 * If the key path doesn't contain any '.', this method simply 316 * invokes -takeValue:forKey:.<br /> 317 * Deprecated ... use -setValue:forKeyPath: instead. 318 */ 319 - (void) takeValue: (id)anObject forKeyPath: (NSString*)aKey; 320 321 /** 322 * Iterates over the dictionary invoking -takeValue:forKey: 323 * on the receiver for each key-value pair, converting NSNull to nil.<br /> 324 * Deprecated ... use -setValuesForKeysWithDictionary: instead. 325 */ 326 - (void) takeValuesFromDictionary: (NSDictionary*)aDictionary; 327 328 /** 329 * Deprecated ... use -setNilValueForKey: instead. 330 */ 331 - (void) unableToSetNilForKey: (NSString*)aKey; 332 333 334 /** 335 * Returns a boolean indicating whether the object pointed to by aValue 336 * is valid for setting as an attribute of the receiver using the name 337 * aKey. On success (YES response) it may return a new value to be used 338 * in aValue. On failure (NO response) it may return an error in anError.<br /> 339 * The method works by calling a method of the receiver whose name is of 340 * the form validateKey:error: if the receiver has implemented such a 341 * method, otherwise it simply returns YES. 342 */ 343 - (BOOL) validateValue: (id*)aValue 344 forKey: (NSString*)aKey 345 error: (out NSError**)anError; 346 347 /** 348 * Returns the result of calling -validateValue:forKey:error: on the receiver 349 * using aPath to determine the key value in the same manner as the 350 * -valueForKeyPath: method. 351 */ 352 - (BOOL) validateValue: (id*)aValue 353 forKeyPath: (NSString*)aKey 354 error: (out NSError**)anError; 355 356 /** 357 * Returns the value associated with the supplied key as an object. 358 * Scalar attributes are converted to corresponding objects.<br /> 359 * The search order is:<br/> 360 * Accessor methods: 361 * <list> 362 * <item>getKey</item> 363 * <item>key</item> 364 * </list> 365 * If the receiver's class allows +accessInstanceVariablesDirectly 366 * it continues with private accessors: 367 * <list> 368 * <item>_getKey</item> 369 * <item>_key</item> 370 * </list> 371 * and then instance variables: 372 * <list> 373 * <item>key</item> 374 * <item>_key</item> 375 * </list> 376 * Invokes -setValue:forUndefinedKey: 377 * if no accessor mechanism can be found 378 * and raises NSInvalidArgumentException if the accessor method takes 379 * any arguments or the type is unsupported (e.g. structs). 380 */ 381 - (id) valueForKey: (NSString*)aKey; 382 383 /** 384 * Returns the object returned by invoking -valueForKeyPath: 385 * recursively on the object returned by invoking -valueForKey: 386 * on the receiver with the first key component supplied by the key path. 387 * The key components are delimited by '.'. 388 * If the key path doesn't contain any '.', this method simply 389 * invokes -valueForKey: . 390 */ 391 - (id) valueForKeyPath: (NSString*)aKey; 392 393 /** 394 * Invoked when -valueForKey: / -storedValueForKey: are called with a key, 395 * which can't be associated with an accessor method or instance variable. 396 * Subclasses may override this method to add custom handling. NSObject 397 * raises an NSUndefinedKeyException, with a userInfo dictionary containing 398 * NSTargetObjectUserInfoKey with the receiver an NSUnknownUserInfoKey with 399 * the supplied key entries.<br /> 400 */ 401 - (id) valueForUndefinedKey: (NSString*)aKey; 402 403 /** 404 * Iterates over the array sending the receiver -valueForKey: 405 * for each object in the array and inserting the result in a dictionary. 406 * All nil values returned by -valueForKey: are replaced by the 407 * NSNull instance in the dictionary. 408 */ 409 - (NSDictionary*) valuesForKeys: (NSArray*)keys; 410 411 @end 412 413 #if defined(__cplusplus) 414 } 415 #endif 416 417 #endif /* GS_API_MACOSX */ 418 419 #endif 420 421