Key Value Coding vs accessor methods in iOS

房东的猫 提交于 2019-12-06 00:12:56

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!