KVC学习笔记

Keys must use ASCII encoding, begin with a lowercase letter, and may not contain whitespace.

----------------------------------------------------------------
valueForKey
If there is no accessor or instance variable for the specified key, then the receiver sends itself a  valueForUndefinedKey:  message. The default implementation of  valueForUndefinedKey:  raises an  NSUndefinedKeyException;  subclasses can  override  this behavior.

The default implementations of  dictionaryWithValuesForKeys:  and  setValuesForKeysWithDictionary:  translates between  NSNull  and  nil  automatically, so your objects don’t have to explicitly test for  NSNull  values

----------------------------------------------------------------
setValue:forKey:
If the specified key does not exist, the receiver is sent a  setValue:forUndefinedKey:  message. The default implementation of  setValue:forUndefinedKey:  raises an  NSUndefinedKeyException;  however, subclasses can override this method to handle the request in a custom manner.

The default implementation invokes  setValue:forKey:  for each key-value pair, substituting  nil  for  NSNull  objects as required.

----------------------------------------------------------------

when an attempt is made to set a non-object
property to a nil value. In this case, the receiver sends itself a setNilValueForKey: message. The default
implementation of setNilValueForKey: raises an NSInvalidArgumentException.
This provides the opportunity to provide appropriate default values for your application, or handle keys that don’t have corresponding accessors in the class.
with " setValue:forKey:  "


The  -  method returns an object, scalar, or a data structure. The alternate naming form  -is  is supported for Boolean properties.


Collection Accessor Patterns for To-Many Properties
There are two variations of collection accessors: indexed accessors for ordered to-many relationships (typically represented by  NSArray)  and unordered accessors for relationships that don’t require an order to the members (represented by  NSSet).


Getter Indexed Accessors

  • -countOfRequired. This is the analogous to the NSArray primitive method count. -objectInAtIndex: or -AtIndexes:. One of these methods must be implemented. They
  • correspond to the NSArray methods objectAtIndex: and objectsAtIndexes:.
  • -get:range:. Implementing this method is optional, but offers additional performance gains. This method corresponds to the NSArray method getObjects:range:.
 
/************************** e.g *********************************************/  
   - (NSUInteger)countOfEmployees {
    return [self.employees count];

   }

   - (id)objectInEmployeesAtIndex:(NSUInteger)index {
    return [employees objectAtIndex:index];

   }

   - (NSArray *)employeesAtIndexes:(NSIndexSet *)indexes {
    return [self.employees objectsAtIndexes:indexes];

   }

- (void)getEmployees:(Employee * __unsafe_unretained *)buffer range:(NSRange)inRange {

    // Return the objects in the specified range in the provided buffer.
    // For example, if the employees were stored in an underlying NSArray
    [self.employees getObjects:buffer range:inRange]; 
}
  

Mutable Indexed Accessors
mutableArrayValueForKey:
  • -insertObject:inAtIndex: or -insert:atIndexes:. At least one of these methods must be implemented. These are analogous to the NSMutableArray methods insertObject:atIndex: and insertObjects:atIndexes:.
  • -removeObjectFromAtIndex: or -removeAtIndexes:. At least one of these methods must be implemented. These methods correspond to the NSMutableArray methods removeObjectAtIndex: and removeObjectsAtIndexes: respectively.
  • -replaceObjectInAtIndex:withObject: or -replaceAtIndexes:with:. Optional. Implement if benchmarking indicates that performance is an issue.
/************************** e.g *********************************************/
- (void)insertObject:(Employee *)employee inEmployeesAtIndex:(NSUInteger)index {
    [self.employees insertObject:employee atIndex:index];
    return; 
}
- (void)insertEmployees:(NSArray *)employeeArray atIndexes:(NSIndexSet *)indexes
{
    [self.employees insertObjects:employeeArray atIndexes:indexes]; 
    return; 
}

- (void)removeObjectFromEmployeesAtIndex:(NSUInteger)index {
    [self.employees removeObjectAtIndex:index]; 
}

- (void)removeEmployeesAtIndexes:(NSIndexSet *)indexes {
    [self.employees removeObjectsAtIndexes:indexes]; 
}

- (void)replaceObjectInEmployeesAtIndex:(NSUInteger)index
                             withObject:(id)anObject {
    [self.employees replaceObjectAtIndex:index withObject:anObject]; 
}

- (void)replaceEmployeesAtIndexes:(NSIndexSet *)indexes
                    withEmployees:(NSArray *)employeeArray {
    [self.employees replaceObjectsAtIndexes:indexes withObjects:employeeArray]; 
}


Getter Unordered Accessors
  • -countOf. Required. This method corresponds to the NSSet method count.
  • -enumeratorOf. Required. Corresponds to the NSSet method objectEnumerator.
  • -memberOf:. Required. This method is the equivalent of the NSSet method member:

/************************** e.g *********************************************/
- (NSUInteger)countOfTransactions {
    return [self.transactions count];

}

- (NSEnumerator *)enumeratorOfTransactions {
    return [self.transactions objectEnumerator];

}

- (Transaction *)memberOfTransactions:(Transaction *)anObject {
    return [self.transactions member:anObject]; 
}


Mutable Unordered Accessors
mutableSetValueForKey:
  • -addObject: or -add:. At least one of these methods must be implemented. These are analogous to the NSMutableSet method addObject:.
  • -removeObject: or -remove:. At least one of these methods must be implemented. These are analogous to the NSMutableSet method removeObject:.
  • -intersect:. Optional. Implement if benchmarking indicates that performance is an issue. It performs the equivalent action of the NSSet method intersectSet:.

/************************** e.g *********************************************/
- (void)addTransactionsObject:(Transaction *)anObject {
    [self.transactions addObject:anObject];

}

- (void)addTransactions:(NSSet *)manyObjects {
    [self.transactions unionSet:manyObjects]; 
}

- (void)removeTransactionsObject:(Transaction *)anObject {
      [self.transactions removeObject:anObject];
}

- (void)removeTransactions:(NSSet *)manyObjects {
      [self.transactions minusSet:manyObjects]; 
}

- (void)intersectTransactions:(NSSet *)otherObjects {
    return [self.transactions intersectSet:otherObjects]; 
}


Validation Method Naming Convention
A validation method has the format  validate:error:

There are three possible outcomes from a validation method:

  1. The object value is valid, so YES is returned without altering the value object or the error.

  2. The object value is not valid and a valid value cannot be created and returned. In this case NO is returned after setting the error parameter to an NSError object that indicates the reason validation failed.

  3. A new object value that is valid is created and returned. In this case YES is returned after setting the value parameter to the newly created, valid value. The error is returned unaltered. You must return a new object, rather than just modifying the passed ioValue, even if it is mutable. 


The example in Listing 2 implements a validation method for a  name  property that ensures that the value object is a string and that the name is capitalized correctly. 
-(BOOL)validateName:(id *)ioValue error:(NSError * __autoreleasing *)outError{
    // The name must not be nil, and must be at least two characters long.
    if ((*ioValue == nil) || ([(NSString *)*ioValue length] < 2)) {
if (outError != NULL) {
    NSString *errorString = NSLocalizedString(
            @"A Person's name must be at least two characters long",

@"validation: Person, too short name error");
NSDictionary *userInfoDict = @{ NSLocalizedDescriptionKey : errorString
};
    *outError = [[NSError alloc] initWithDomain:PERSON_ERROR_DOMAIN
                                            code:PERSON_INVALID_NAME_CODE
                                        userInfo:userInfoDict];

          }

          return NO;
     }
     return YES; 
}


Invoking Validation Methods
You can call validation methods directly, or by invoking  validateValue:forKey:error:  and specifying the key.

Warning:  An implementation of set:  for a property should never call the   validation methods.

Automatic Validation
In general, key-value coding does not perform validation automatically—it is your application’s responsibility to invoke the validation methods.

Core Data  automatically performs validation when the managed object context is saved; in OS X, Cocoa bindings allow you to specify that validation should occur automatically


Representing Non-Object Values
The default implementations of  valueForKey:  and  setValue:forKey:  provide support for automatic object wrapping of the non-object data types, both scalars and structs.
即对此两方法的调用自动转换为对应getter和setter方法的Values



Collection Operators
The key path on the left side of the collection operator, if present, determines the array or set, relative to the receiver, that is used in the operation. The key path on the right side of the operator specifies the property of the collection that the operator uses.
Simple Collection Operators
Simple collection operators operate on the properties to the right of the operator in either an array or set
@avg       作用于ritghPath
@count    作用于leftPath  the key path to the right of the operator is ignored.
@max      作用于ritghPath  If the value of the right side of the key path is nil, it is ignored.
@min       同上
@sum      同上

Object Operators
@distinctUnionOfObjects     作用于ritghPath. This operator raises an exception if any of the leaf objects is nil. returns a array
@unionOfObjects     同上 returns a array

Array and Set Operators
The array and set operators operate on nested collections, that is, a collection where each entry contains a collection
@distinctUnionOfArrays     同distinctUnionOfObjects returns a array
@unionOfArrays      同上 returns a array
@distinctUnionOfSets   同上  returns a set


Accessor Search Patterns for Simple Attributes
Default Search Pattern for  setValue:forKey:
  1. The receiver’s class is searched for an accessor method whose name matches the pattern set:.
  2. If no accessor is found, and the receiver’s class method  accessInstanceVariablesDirectly  returns  YES,  the receiver is searched for an instance variable whose name matches the pattern  _, _is, ,  or  is,  in that order.
  3. If a matching accessor or instance variable is located, it is used to set the value. 注: 跟直接属性调用accessor不同, setValue可能不经过accessor
  4. If no appropriate accessor or instance variable is found, setValue:forUndefinedKey: is invoked for the receiver.
Default Search Pattern for  valueForKey:
proxy object: NSArray 或 NSSet
  1. Searches the class of the receiver for an accessor method whose name matches the pattern get, or is,
  2. Otherwise, searches countOf and objectInAtIndex: and AtIndexes:……………..If the countOf method and at least one of the other two possible methods are found,  a collection proxy object that responds to all NSArray methods is returned. 
  3. Otherwise, searches the class of the receiver for a threesome of methods whose names match the patterns countOf, enumeratorOf, and memberOf: (corresponding to the primitive methods defined by the NSSet class). ……………..If all three methods are found, a collection proxy object that responds to all NSSet methods is returned.
  4. Otherwise, if the receiver's class method accessInstanceVariablesDirectly returns YES, the class of the receiver is searched for an instance variable whose name matches the pattern _, _is, , or is,
  5. If none of the above situations occurs, returns a result the default implementation invokes valueForUndefinedKey:

Accessor Search Pattern for Ordered Collections
The default search pattern for   mutableArrayValueForKey:   is as follows:
  proxy object : NSMutableArray
  1. searches for a pair of methods whose names match the patterns insertObject:inAtIndex: and removeObjectFromAtIndex: , or methods matching the pattern insert:atIndexes: and removeAtIndexes:
  2. Otherwise,  searches set: to response the original receiver of mutableArrayValueForKey:
  3. Otherwise, if the receiver's class responds YES to accessInstanceVariablesDirectly, the receiver's class is searched for an instance variable whose name matches the pattern _ or
  4. Otherwise, returns a mutable collection proxy object that results in a setValue:forUndefinedKey: message being sent to the original receiver of the mutableArrayValueForKey: message whenever the proxy receives an NSMutableArray message.
Note:  The repetitive  set messages implied by the description in step 2 are a potential performance problem. For better performance, implement methods that fulfill the requirements for Step 1 in your key-value coding-compliant class.


Accessor Search Pattern for Uniquing Ordered Collections
mutableOrderedSetValueForKey:
proxy object : NSMutableOrderedSet
  1. Searches insertObject:inAtIndex: and removeObjectFromAtIndex: and also insert:atIndexes: and removeAtIndexes:……….  If at least one insertion method and at least one removal method are found each NSMutableOrderedSet message sent to the collection proxy object will result in some combination of insertObject:inAtIndex:, removeObjectFromAtIndex:, insert:atIndexes:, and removeAtIndexes: messages being sent to the original receiver of mutableOrderedSetValueForKey:.
  2. Otherwise, searches set
  3. Otherwise, if the receiver's class responds YES to accessInstanceVariablesDirectly, the receiver's class is searched for an instance variable whose name matches the pattern _ or
  4. Otherwise, returns a mutable collection proxy object that results in a setValue:forUndefinedKey:

Accessor Search Pattern for Unordered Collections
mutableSetValueForKey:
proxy object : NSMutableSet
  1. Searches addObject: and removeObject: and also add: and remove: (corresponding to NSMutableSet methods unionSet: and minusSet:). 
  2. If the receiver is a managed object, the search pattern does not continue as it would for non-managed objects.

  3. Otherwise, searches set
  4. Otherwise, if the receiver's class responds YES to accessInstanceVariablesDirectly, the receiver's class is searched for an instance variable whose name matches the pattern _ or
  5. Otherwise, returns a mutable collection proxy object that results in a setValue:forUndefinedKey:

你可能感兴趣的:(obj-c,iphone开发)