objective-c - 在 Cocoa 中编写我自己的 @dynamic 属性

标签 objective-c cocoa

假设(为了论证)我有一个包含 NSDictionary 的 View 类。我想要一大堆属性,所有这些属性都访问该字典的成员。

例如,我想要@property NSString* title@property NSString* author

对于这些属性中的每一个,实现都是相同的:对于 getter,调用 [dictionary objectForKey:propertyName];,对于 setter,调用 setObject:forKey:。

编写所有这些方法将花费大量时间并使用大量复制和粘贴代码。有没有办法自动生成它们,就像 Core Data 对 NSManagedObject 子类的 @dynamic 属性所做的那样?需要明确的是,我只希望通过这种方式访问​​我在 header 中定义的属性,而不仅仅是任意键。

我遇到过 valueForUndefinedKey: 作为键值编码的一部分,它可以处理 getter,但我不完全确定这是否是最好的方法。

我需要这些是显式属性,以便我可以在 Interface Builder 中绑定(bind)到它们:我最终计划为此 View 编写一个 IB 调色板。

(顺便说一句,我知道我使用 NSDictionary 来存储这些的示例有点做作。我实际上是在编写 WebView 的子类,属性将引用 HTML 元素的 ID,但这对逻辑并不重要我的问题!)

最佳答案

在阅读了 objective-c 运行时文档后,我设法自己解决了这个问题。

我实现了这个类方法:

+ (BOOL) resolveInstanceMethod:(SEL)aSEL
{
    NSString *method = NSStringFromSelector(aSEL);

    if ([method hasPrefix:@"set"])
    {
        class_addMethod([self class], aSEL, (IMP) accessorSetter, "v@:@");
        return YES;
    }
    else
    {
        class_addMethod([self class], aSEL, (IMP) accessorGetter, "@@:");
        return YES;
    }
    return [super resolveInstanceMethod:aSEL];
}

后跟一对 C 函数:

NSString* accessorGetter(id self, SEL _cmd)
{
    NSString *method = NSStringFromSelector(_cmd);
    // Return the value of whatever key based on the method name
}

void accessorSetter(id self, SEL _cmd, NSString* newValue)
{
    NSString *method = NSStringFromSelector(_cmd);

    // remove set
    NSString *anID = [[[method stringByReplacingCharactersInRange:NSMakeRange(0, 3) withString:@""] lowercaseString] stringByReplacingOccurrencesOfString:@":" withString:@""];

    // Set value of the key anID to newValue
}

由于此代码尝试实现在类上调用但尚未实现的任何方法,因此如果有人尝试调用您所期望的内容,则会导致问题。我计划添加一些合理性检查,以确保名称符合我的预期。

关于objective-c - 在 Cocoa 中编写我自己的 @dynamic 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3560364/

相关文章:

iphone - 如何使用 RegexKitLite 删除任意两个单词之间的空格/空白?

ios - 使用常规 UIViewController 分页解析查询

objective-c - KVO for one-to-many but NSNull object passed into observeValueForKeyPath

iphone - AFNetworking 和网络错误

python - 在 Python 中使用 dock 的基本 cocoa 应用程序,但不使用 Xcode 和所有其他功能

objective-c - 从 NSData 创建多个 NSDocument 的最简洁方法

macos - 视网膜问题 (OS X)

objective-c - 如何在 Objective-C 中获取我的文件大小

objective-c - NSButton 在 mouseup 上引发单击事件

macos - 使用键路径访问 NSArray 中的对象