I'm trying to understand some theory part in Objective C related to KVC. Following is the example I've done.
I'm having class call Cookie and it has a property like below
@property NSString *name;
Next, I have another class call Person and it has following property
@property Cookie *cookie;
Inside Person implementation file
#import "Cookie.h"
- (id)init
{
self = [super init];
if (self) {
_cookie = [[Cookie alloc] init];
}
return self;
}
In my ViewContrtoller I can write following two options to get the same result.
Using KVC :
[me valueForKeyPath:@"cookie.name"]
Using accessor methods :
[[me cookie] name]
To write accessor method , I had to import the Cookie class but doesn't need when using KVC.
Apart from that, what are the benefit of using KVC instead or using accessor methods? Is there any performance issue or security issue or good coding practice or any other benefit?
One situation where i found KVC very handy was when i had to perform some kind of operation on a collection object such as finding the average of a particular value.Specifically I used KVC operators.
For example
[myDict valueForKey:@"gamePoints"] valueForKey:@"doubleValue"] valueForKeyPath:@"@max.self"];
This will help you find the maximum value for the property 'gamePoints' from among an array of dictionaries/ objects.
Here is an excellent article by Mattt Thompson Hope this contributes to what you are looking for.
There's no particular benefit in this case to using KVC. In general, you should prefer to use the accessors or dot syntax (e.g. me.cookie.name
) when you can.
KVC is for when the name of the property you want to access is dynamic. It's not known at compile time. It comes from data (including a NIB, in the case of bindings on OS X) or is computed.
According to the Apple Docs:
Though key-value coding is efficient, it adds a level of indirection that is slightly slower than direct method invocations. You should use key-value coding only when you can benefit from the flexibility that it provides.
But I think this is probably a little over-cautious; I doubt you need worry too much unless your app is very performance sensitive.
Beside the given answers (+1) you get the advantage of identifier completion in Xcode which reduces the probability of typos. Importing the class is a good strategy, if you use it semantically. Look at it as a "bill of things I use", which can be helpful for understanding your code.
Great place to use KVO is unit testing. When you have following class interface:
@interface ServerCommunicationManager : NSObject
{
NSMutableArray *commandQueue;
BOOL chanelFree;
}
- (void)send:(NSDictionary *)dictionary;
@end
And then send implementation:
- (void)send:(NSDictionary *)json
{
if ( YES == chanelFree ) {
// send command immediately
} else {
[commandQueue addObject:json];
}
}
If we want to test send implementation without exposing commandQueue(hence without braking encapsulation) we could get use of KVO:
-(void)testSend
{
ServerCommunicationManager* aTestObj = [ServerCommunicationManager new];
//prepare conditions
[aTestObj setValue:@NO forKey:@"channelFree"];
NSDictionary* dummyReq = @{};
[aTestObj send:dummyReq];
//check commandQueue state
XCTAssertEqualObjects(dummyReq, [[aTestObj valueForKey:@"commandQueue"] firstObject]);
XCTAssertTrue(1 == [[aTestObj valueForKey:@"commandQueue"] count]);
//more tests
}
KVC allows you to do KVO: That is, if you are observing a variable, you will only be notified of its changes if and only if the changes take place using KVC. If you modify a variable directly using its setter you are not going to be notified of its changes
来源:https://stackoverflow.com/questions/28849318/key-value-coding-vs-accessor-methods-in-ios