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

3

我正在尝试理解与KVC相关的Objective C的一些理论部分。以下是我所做的示例。

我有一个名为Cookie的类,它有一个如下的属性

@property NSString *name;

接下来,我有另一个名为Person的类,它具有以下属性。
@property Cookie *cookie;

人员实现文件内部
#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个回答

2
我发现KVC非常方便的一个情况是,当我需要对集合对象执行某种操作,比如找到特定值的平均值时。具体来说,我使用了KVC运算符。
例如:
[myDict valueForKey:@"gamePoints"] valueForKey:@"doubleValue"] valueForKeyPath:@"@max.self"];

这将帮助您在字典/对象数组中找到属性“gamePoints”的最大值。 这里有一篇由Mattt Thompson撰写的优秀文章,希望对您寻找的内容有所贡献。

2
在这种情况下,使用KVC没有特别的好处。一般来说,应该尽可能使用访问器或点语法(例如me.cookie.name)。
当您要访问的属性名称是动态的时候,可以使用KVC。它在编译时不知道。它来自数据(包括在OS X上绑定的NIB)或计算得出。

2
根据Apple Docs的说法:
尽管键值编码是高效的,但它增加了一层间接性,比直接方法调用略慢。只有在需要其提供的灵活性时,才应使用键值编码。
但我认为这可能有点过于谨慎了;除非您的应用程序非常注重性能,否则不必太担心。

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
}

0
除了给出的答案(+1),您还可以在Xcode中获得标识符完成的优势,这可以降低打字错误的概率。如果您在语义上使用它,导入类是一个好策略。将其视为“我使用的事物清单”,这对于理解您的代码可能会有帮助。

-1

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接