当我开始开发iPhone时,我在某处读到可以将一个键值对附加到UIView.我知道所有UIViews都可以用作字典来存储你可能想要附加到它们的任何数据,以防止不必要的子类化.但是,我到处搜索找到了参考资料,并试图自己实现这种行为是徒劳的.
我尝试过这样的事情:
UIView *myView = [[UIView alloc] init];
[myView setValue:@"hello" forKey:@"world"];
Run Code Online (Sandbox Code Playgroud)
但这似乎不起作用.我认为上面的代码所做的是尝试将值@"hello"分配给属性@"world" - 这不是我想要的.
我正在努力实现的目标是什么?
这里的任何帮助将不胜感激.
谢谢!
缺口.
我正在尝试使用键值观察来为NSMutableArray工作.下面是MyObservee的.h文件,观察到的类:
@interface MyObservee : NSObject {
@private int someValue;
@private NSMutableArray *someArray;
}
@property (readwrite,assign) int someValue;
- (NSMutableArray *)someArray;
@end
Run Code Online (Sandbox Code Playgroud)
MyObserver类实现observeValueForKeyPath:ofObject:change:context:.这是我添加观察者的方式:
MyObservee *moe = [[MyObservee alloc] init];
MyObserver *mobs = [[MyObserver alloc] init];
[moe addObserver:mobs
forKeyPath:@"someArray"
options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
context:NULL];
[moe.someArray addObject:@"hi there"];
Run Code Online (Sandbox Code Playgroud)
为什么addObject:message不会作为someArray键路径的更改而触发?我觉得这里有一些我不完全理解的东西.
在阅读了键值编码编程指南,键值观察编程指南和模型对象实现指南,以及阅读关于该主题的许多StackOverflow条目并尝试各种建模场景之后,我觉得我对如何建模我的数据.
我最终使用所有属性的声明属性和一个由私有ivars支持的关系.对于需要可私有写入的只读属性,我readonly在.h接口声明中使用该属性,然后readwrite使用.m文件中声明的类扩展中的属性重新声明该属性.在类方法中,我总是使用带有点语法的属性访问器,并且永远不会直接访问私有的ivars.
然而,有一个方面让我感到困惑:如何正确地建模到多个关系,特别是当集合是公开不可变的,但私下可变的(即模型对象的消费者不能添加或删除集合中的对象,但该集合的内容由该类私人管理).
我明白了如何实现一对多关系(KVC的存取方法countOf<Key>,objectsIn<Key>AtIndex等等),这是我到目前为止一直在跟随的路线.
但是,我已经看到一些示例代码使用声明的属性来公开关系,不实现KVC访问器方法,但仍然是Key-Value可观察的.例如:
@interface MyModel : NSObject
{
// Note that the ivar is a mutable array,
// while the property is declared as an immutable array.
@private NSMutableArray *transactions_;
}
@property (nonatomic, retain, readonly) NSArray transactions;
@end
--------------------
@implementation MyModel
@synthesize transactions = transactions_;
- (void)privateMethodThatManagesTransactions
{
[[self mutableArrayValueForKey:@"transactions"] addObject:t];
}
@end
Run Code Online (Sandbox Code Playgroud)
如果使用者对象将自身添加MyModel为"transactions"关键路径的实例的观察者,则只要transactions通过该 …
我有一个看起来像这样的课程:
@interface Properties : NSObject {
@private
NSNumber* prop1;
NSNumberBool* prop2;
//etc
Run Code Online (Sandbox Code Playgroud)
其中NSNumberBool是typedef:
// in MyApp_Prefix.pch
typedef NSNumber NSNumberBool;
Run Code Online (Sandbox Code Playgroud)
我有所有必需的@property和@synthesize声明来制作prop1和prop2属性.
所有编译和工作正常,直到我试图通过[myProperties valueForKey:@"prop2"]访问prop2.这给了我一个"类不符合键值"的错误.但是,许多类似的调用工作正常:
myProperties.prop2; //works
[myProperties prop2]; //works
[myProperties valueForKey:@"prop1"]; //works
[myProperties valueForKey:@"prop2"] // throws NSUnknownKeyException ??
Run Code Online (Sandbox Code Playgroud)
这里发生了什么,我该如何解决?
谢谢,
我正在NSManagedObject使用以下命令初始化子类:
- (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues
Run Code Online (Sandbox Code Playgroud)
我也故意给它未定义的键,当然应该抛出异常.
所以,我已经实施了:
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
Run Code Online (Sandbox Code Playgroud)
如果未定义某个键,则将其映射到正确的键.
但是,我的实现永远不会被调用,而是NSManagedObject使用了实现,这反过来仍然会抛出异常.
是否存在阻止setValuesForKeysWithDictionary:使用任何子NSManagedObject类实现的行为(或错误)setValue:forUndefinedKey:?
按要求添加代码,但由于我只是实现了一个现有的方法,但是没有被调用,我不知道它会有多大的帮助:
在上下文中:
- (Company*)companyWithDictionary:(NSDictionary*)values{
Company* newCompany = (Company*)[NSEntityDescription insertNewObjectForEntityForName:@"Company" inManagedObjectContext:self];
[newCompany setValuesForKeysWithDictionary:values];
return newCompany;
}
Run Code Online (Sandbox Code Playgroud)
在Company子类中(从未调用过):
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
if([key isEqualToString:idKey]){
[self setValue:value forKey:@"uniqueID"];
}else if([key isEqualToString:descriptionKey]){
[self setValue:value forKey:@"descriptionText"];
}else if([key isEqualToString:timeUpdatedKey]){
[self setValue:value forKey:@"dateUpdated"];
}else{
[super setValue:value forUndefinedKey:key];
}
}
Run Code Online (Sandbox Code Playgroud) iPhone键值编码是否有办法测试一个类是否接受给定的键?
也就是说,如果没有实现目标类的valueForUndefinedKey:或setValue:forUndefinedKey:方法,我希望能够做到这样的事情:
if ([targetObject knowsAboutKey: key]) {
[targetObject setValue: value forKey: key];
}
Run Code Online (Sandbox Code Playgroud) 我无法弄清楚@UnionOfObjects提供的简单valueForKey:或valueForKeyPath:不能做什么.
@unionOfObjects运算符返回一个数组,该数组包含由运算符右侧的键路径指定的属性中的不同对象.与"@distinctUnionOfObjects"不同,不会删除重复的对象.以下示例返回事务中事务的收款人属性值:
Run Code Online (Sandbox Code Playgroud)NSArray *payees = [transactions valueForKeyPath:@"@unionOfObjects.payee"];由此产生的收款人阵列包含以下字符串:绿色电力,绿色电力,绿色电力,汽车贷款,汽车贷款,汽车贷款,通用电缆,通用电缆,通用电缆,抵押贷款,抵押贷款,抵押贷款,动物医院.
在上面的例子中,
NSArray *payees = [transactions valueForKey:@"payee"];
Run Code Online (Sandbox Code Playgroud)
将返回相同的值数组,但代码更少.我错过了什么?
例如,我有一个具有三个属性的对象:firstName,middleName,lastName.
如果我想使用NSPredicate在所有属性中搜索字符串"john".
而不是像以下那样创建谓词:
[NSPredicate predicateWithFormat:@"(firstName contains[cd] %@) OR (lastName contains[cd] %@) OR (middleName contains[cd] %@)", @"john", @"john", @"john"];
我可以这样做:
[NSPredicate predicateWithFormat:@"(all contains[cd] %@), @"john"];
当我使用Predicate过滤自定义Swift类的数组时,我得到错误:
***NSForwarding:警告:类'Plantivo1_6.Seed'的对象0x78ed21a0没有实现methodSignatureForSelector: - 提前故障
无法识别的选择器 - [Plantivo1_6.Seed valueForKey:]
如果我没记错的话,这可以在Objective-C中使用.我的错是什么?
let names = ["Tom","Mike","Marc"]
println(names)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", "om")
let array = (names as NSArray).filteredArrayUsingPredicate(searchPredicate)
println(array)
println()
let mySeed1 = Seed() // Seed is a class with a `culture` String property
let mySeed2 = Seed()
let mySeed3 = Seed()
mySeed1.culture = "Tom"
mySeed2.culture = "Mike"
mySeed3.culture = "Marc"
let mySeeds = [mySeed1,mySeed2,mySeed3]
println(mySeeds)
let searchPredicate1 = NSPredicate(format: "SELF.culture CONTAINS[c] %@", "om")
let array1 = (mySeeds as NSArray).filteredArrayUsingPredicate(searchPredicate1) …Run Code Online (Sandbox Code Playgroud) 我的团队已决定新文件应该用swift编写,我发现在Objective-C对象中使用KVC在Swift对象上设置属性有一个奇怪的问题.
我的Objective-C设置了这样的属性: [textObject setValue:0.0 forKey:@"fontSize"]
我的Swift对象(textObject)具有此属性的自定义setter/getter.
var fontSize: CGFloat? {
get {
return internalTextGraphic?.fontSize
}
set {
internalTextGraphic?.fontSize = newValue
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我在其中设置断点set,它永远不会被击中.
我有Objective-C对象也得到同样的调用,我只是实现
-setFontSize,并执行正确.
为什么我似乎无法进入我的set方法-setValueForKey?我有100%确认textObject存在并且是正确的类型.
编辑:
马丁R是正确的,我不得不使类型不可选.这是我的工作代码:
var fontSize: CGFloat {
get {
var retFontSize: CGFloat = 0.0
if let fontSize = internalTextGraphic?.fontSize {
retFontSize = fontSize
}
return retFontSize
}
set {
if let textGraphic = internalTextGraphic {
textGraphic.fontSize = newValue
}
}
}
Run Code Online (Sandbox Code Playgroud) key-value-coding ×10
cocoa ×3
cocoa-touch ×2
ios ×2
iphone ×2
kvc ×2
nspredicate ×2
objective-c ×2
swift ×2
collections ×1
core-data ×1
dictionary ×1
model ×1
typedef ×1