关键值编码与iOS中的访问器方法

时间:2015-03-04 08:04:57

标签: ios objective-c kvc

我试图理解目标C中与KVC相关的一些理论部分。以下是我已经完成的例子。

我有课程调用Cookie,它有一个如下所示的属性

@property NSString *name;

接下来,我有另一个类调用Person,它有以下属性

@property Cookie *cookie;

Inside Person实施文件

#import "Cookie.h"

- (id)init
{
    self = [super init];
    if (self) {
        _cookie = [[Cookie alloc] init];
    }
    return self;
}

在我的ViewContrtoller中,我可以编写以下两个选项来获得相同的结果。

使用KVC:

[me valueForKeyPath:@"cookie.name"]

使用存取方法:

[[me cookie] name]

要编写访问器方法,我必须导入Cookie类,但在使用KVC时并不需要。

除此之外,使用KVC或使用访问器方法有什么好处?是否有任何性能问题或安全问题或良好的编码实践或任何其他好处?

6 个答案:

答案 0 :(得分:2)

我发现KVC非常方便的一种情况是我必须对集合对象执行某种操作,例如查找特定值的平均值。特别是我使用了KVC操作符。

例如

[myDict valueForKey:@"gamePoints"] valueForKey:@"doubleValue"] valueForKeyPath:@"@max.self"];

这将帮助您找到该物业的最大价值' gamePoints'来自一系列词典/对象。

Here is an excellent article by Mattt Thompson 希望这有助于你所寻找的东西。

答案 1 :(得分:2)

根据Apple Docs

  

虽然键值编码是有效的,但它增加的间接级别比直接方法调用稍慢。只有在您可以从其提供的灵活性中受益时,才应使用键值编码。

但我认为这可能有点过于谨慎;我怀疑你需要太多担心,除非你的应用程序对性能非常敏感。

答案 2 :(得分:1)

在这种情况下,使用KVC没有特别的好处。通常,您应该尽可能使用访问者或点语法(例如me.cookie.name)。

KVC适用于您要访问的媒体资源的名称是动态的。它在编译时不知道。它来自数据(包括NIB,在OS X上绑定的情况下)或计算。

答案 3 :(得分:0)

除了给定的答案(+1)之外,您还可以在Xcode中获得标识符完成的优势,从而降低拼写错误的可能性。如果您在语义上使用它,导入类是一个很好的策略。将其视为“我使用的物品清单”,这有助于理解您的代码。

答案 4 :(得分:0)

使用KVO的好地方是单元测试。如果您有以下类接口:

@interface ServerCommunicationManager : NSObject
{
    NSMutableArray *commandQueue;
    BOOL chanelFree;
}

- (void)send:(NSDictionary *)dictionary;
@end

然后发送实现:

- (void)send:(NSDictionary *)json
{
    if ( YES == chanelFree ) {
        // send command immediately

    } else {
        [commandQueue addObject:json];
    }

}

如果我们想在不暴露commandQueue的情况下测试发送实现(因此没有制动封装),我们可以使用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
}

答案 5 :(得分:-1)

KVC允许您进行KVO:也就是说,如果您正在观察变量,当且仅当使用KVC进行更改时,才会通知您的更改。如果直接使用其setter修改变量,则不会收到有关其更改的通知