我正在尝试在cocoa中实现一个简单的对象桥,其中桥对象充当某个任意其他NSObject实例的kvo/bindings兼容的drop.
这是我的问题(下面代码中的更多细节):
桥对象充当Person-Object的drop in,具有名为name的NSString*属性和Address*属性地址.绑定到Bridge的keyPath"name"或"address"可以很好地工作.将某个对象绑定到桥的keyPath"address.street"并为Person的地址属性设置新的Address-Object时,麻烦就开始了.这导致与KVO相关的异常如下所示:
Cannot remove an observer <NSKeyValueObservance 0x126b00> for the key path "street" from <Address 0x12f1d0> because it is not registered as an observer
即使桥接器注意到"地址"-Property中的更改并发出willChangeValueForKeyPath/didChangeValueForKeyPath元组,也会发生这种情况.
下面的代码产生了问题.它是自包含的objective-c代码,可以保存在文件"BridgeDemo.m"中并使用编译运行
gcc -o test BridgeDemo.m -framework AppKit -framework Foundation; ./test
Run Code Online (Sandbox Code Playgroud)
如果您知道这个问题的解决方案或者可以为我提供更好的方法来解决同样的问题,那么你就会让我成为一个非常开心的程序员!
BridgeDemo.m:
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
/* --- Address ----------------------------------------- */
@interface Address : NSObject {
NSString* street;
NSNumber* zipCode;
NSString* city;
}
@property(retain) NSString* street;
@property(retain) NSNumber* zipCode;
@property(retain) NSString* city;
@end
@implementation Address …Run Code Online (Sandbox Code Playgroud) 我很欣赏一些关于我正在考虑使用的特定方法的反馈.场景如下.
我有一个对象(让我们称之为MObject),它有许多属性,比如x和y坐标,高度和宽度.属性根据KVC指南(MObject.x; MObject.height等)命名.我的下一个任务是读入描述此MObject的XML文件.不幸的是,XML元素的命名方式不同 - X和Y,高度和宽度(注意大小写).
理想情况下,XML元素将与MObject的属性匹配.在这种情况下,我可以使用KVC并避免一大堆代码:
for (xmlProperty in xmlElement)
{
[MObject setValue:xmlProperty.value forKey:xmlProperty.name].
}
Run Code Online (Sandbox Code Playgroud)
解决这个问题的一种方法是使用不区分大小写的键.我从哪里开始呢?还有其他更好的解决方案吗?
建议非常感谢.
在Apple上的Objective-C中,有一种称为"键值编码"的东西,它允许您使用类似于文件系统路径的字符串遍历对象图.有一个非正式的协议(即接口),允许对象根据他们要求的"密钥"返回值.例如,默认是返回由键命名的字段的值,而像NSDictionaries这样的关系集合可以实现更有趣的行为.
伪代码示例:
foo.bar = new baz();
foo.bar.mymap = new map();
foo.bar.mymap['bom'] = 2;
foo.valueForKeyPath("bar.mymap.bom") # 2
Java有这样的东西吗?这很容易实现,但我想我先看看.
给定Foo类的对象foo,我想执行以下操作:
NSString *key = @"some key";
id myObj = [foo valueForKey: key];
Run Code Online (Sandbox Code Playgroud)
并让myObj等于foo.
如果没有在Foo上定义类别,有没有办法做到这一点?
这个问题实际上是在寻找我知道存在但却找不到的特定类.
几周前,我读了一篇文章,概述了一个使用KVC的帮助类 - 它允许你封装KVC订阅,这样你就可以观察到多个值,而不必经过相同的hander方法,并且还清理了KVC观察者更安全(因为KVC清理非常挑剔且容易出现异常).
所以,在回复中,我正在寻找之前遇到过的助手类,或其他尝试包装KVC以使其更安全和更适合一般用途的例子.
根据Apple自己的建议,当手动设置符合KVC/KVO标准的访问器时,应该包括BOTH KVO方法willChange和didChange.这就是我在所有手动访问器方法中所做的.
然而,observeValueForKeyPath:ofObject:change:context使用完全相同的字典内容来调用KVC方法的每一半(将要和做过).
当使用选项注册观察者时:NSKeyValueObservingOptionPrior观察者仍然被调用两次 - 每半次一次 - 并且再次使用相同的字典内容,仅保存字典中包含键'notificationIsPrior'的差异.
现在,当KVO用于改变"CPU价格昂贵"的属性时 - 比如改变颜色或重新绘制大而精细的设计,只有对'didChange'采取行动并忽略(或至少分离出)'willChange才有意义".在过去,我通过将密钥字符串转换为枚举列表元素来实现此目的,该元素返回左移'1'并使用该数字在收到第一个调用时设置32或64位整数的标志标志在第二个重置,我执行CPU密集型操作.
然而,令我感到震惊的是,对于每个案例来说,这都是一个非常重要的开销.有没有人有任何其他'首选'的方法来区分'willChange'和'didChange'的回调而不允许两次完成相同的处理?
我已经仔细搜索了Apple自己的文档和这个帮助小组的大量替代品,但Apple自己的doc实际上并没有详细介绍这个主题,而且这个小组中的一些人也有类似的问题摔跤.在任何情况下都没有提供确定的解决方案.如果有人知道更好的方式 - 除了用交替的旗帜躲避'willChange' - 我会非常感激.(为什么Apple不能在更改字典中包含'阶段'键?)
我有四个绑定到模型键路径的文本字段.如果在文本字段中输入了数字,则一切都按计划进行.但是,如果该号码被删除,那么我在控制台中收到错误:
[温度0x1003144b0 setNilValueForKey]:无法将nil设置为键rankine的值
我尝试使用setNilValueForKey修复此问题,但它似乎不起作用(请参阅Temperature.h文件底部的代码).有关如何解决此问题的任何建议都会有所帮助.
#import <Foundation/Foundation.h>
@interface Temperature : NSObject {
double celsius;
}
- (void)setCelsius:(double)degreesC;
- (double)celsius;
- (void)setKelvin:(double)degreesK;
- (double)kelvin;
- (void)setFahrenheit:(double)degreesF;
- (double)fahrenheit;
- (void)setRankine:(double)degreesR;
- (double)rankine;
@end
Run Code Online (Sandbox Code Playgroud)
和
#import "Temperature.h"
@implementation Temperature
+ (NSSet *)keyPathsForValuesAffectingFahrenheit {
return [NSSet setWithObject:@"celsius"];
}
+ (NSSet *)keyPathsForValuesAffectingKelvin {
return [NSSet setWithObject:@"celsius"];
}
+ (NSSet *)keyPathsForValuesAffectingRankine {
return [NSSet setWithObject:@"celsius"];
}
- (void)setCelsius:(double)degreesC {
celsius = degreesC;
}
- (double)celsius {
return celsius;
}
- (void)setKelvin:(double)degreesK {
[self setCelsius:degreesK - 273.15]; …Run Code Online (Sandbox Code Playgroud) 我正在阅读:To-Many Properties的集合访问器模式,但我不确定我在哪里或应该使用它.有人可以指出一些我可以使用的方案Collection Accessor Patterns for To-Many Properties来使我的代码更好或使我的代码编写更容易吗?
最近我使用协议func setValue(_ value: AnyObject?, forKey key: String)的功能通过以下方式NSKeyValueCoding更改 a 的文本颜色:UIPickerDate
class ColoredDatePicker: UIDatePicker {
var changed = false
override func addSubview(view: UIView) {
if !changed {
changed = true
self.setValue(UIColor(red: 0.42, green: 0.42, blue: 0.42, alpha: 1), forKey: "textColor")
}
super.addSubview(view)
}
}
Run Code Online (Sandbox Code Playgroud)
关于这个问题的答案。它工作完美。
但我在这里的回答是:
我如何知道该类提供的名称(如textColor上面使用的)是什么?
我试图在文档中找到任何获取所有名称的内容,但到目前为止,我还没有找到任何内容来获取类提供的密钥,如上述情况。
Objective-C 有一种setValue方法允许开发人员通过字段名称为字段设置特定值。
我如何在 Swift 中做到这一点而不继承 NSObject 并实际使用该setValue方法?
key-value-coding ×10
cocoa ×4
objective-c ×4
ios ×3
swift ×2
callback ×1
iphone ×1
java ×1
null ×1