我已经在SO上查看了使用键值观察的示例NSArray(或者NSMutableArray),显然你需要使用NSArrayController(不像KVO我不熟悉的),但我没有找到如何执行此操作的具体示例.有人可以解释一些示例代码吗?
例如,如果我有一个GameModel代表其播放器名称NSArray (playerNameArray)的a NSStrings.我想观察那些字符串(视图控制器观察模型的数据)来更新视图中的各种内容.
如何获得播放器名称数组已更改的通知?
编辑:iOS SDK甚至支持NSArrayController吗?如果没有,还有另一种方式吗?
iphone objective-c key-value-observing nsarray nsarraycontroller
运行项目时,我在输出窗口中收到以下内容:
An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: connection.messageQueue
Observed object: <Client: 0x10011ddb0>
...
Run Code Online (Sandbox Code Playgroud)
你明白了.问题是,我不知道为什么会这样.然而,似乎一切正常.这是导致问题的代码:
-(id) initWithIdentifier:(NSString*)ident andClient:(Client*)chatClient {
if(![super initWithNibName:@"ChatView" bundle:nil]) {
return nil;
}
[self setTitle: ident];
client = chatClient;
[self setIdentifier:ident];
inContext = false;
[client addObserver:self forKeyPath:@"connection.messageQueue" options:NSKeyValueObservingOptionNew context:NULL];
return self;
}
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
NSAttributedString* rar = [[NSAttributedString alloc] initWithString:@"test"];
[[textView textStorage] appendAttributedString:rar];
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
Run Code Online (Sandbox Code Playgroud)
我以为我会显示与此相关的所有代码.该类只有几个方法,所以这就是你需要看到的.我甚至没有使用这个改变,我只是在KVO事件被解雇时采取"测试".
随着消息一直进入,堆栈跟踪变得非常快.但似乎一切都运转正常.
有线索吗?
我正在扩展UIButton通用功能,以根据显示的标题更改某些外观属性.
为此,我需要检测并响应"state"属性的变化.这样,如果用户为不同的状态设置了不同的标题,我确保正确调整外观.我以为我需要使用某种KVO,如下所示:
[self addObserver:self
forKeyPath:@"state"
options:NSKeyValueObservingOptionNew
context:nil];
Run Code Online (Sandbox Code Playgroud)
但这似乎没有触发@"state"或@"currentTitle"的observeValueForKeyPath:...方法.我假设这是因为UIButton没有为这些属性实现KVO模式.
我不想只听点击.这些事件导致状态改变,但不是唯一的潜在原因.
有没有人知道如何倾听和回应UIButton的状态变化?
谢谢
因为我在过去几年中学到了一些东西,所以只是一个注释;).
我已经和一些知道的苹果人谈过了,而且KVO没有在国家财产上工作的原因是因为UIKit的NONE肯定是符合KVO的.在这里值得重复的思考 - 如果你试图听取UIKit框架类的任何属性,请注意它可能有效,但是没有得到官方支持,可能会在不同的iOS版本上中断.
使用自定义NSOperation子类时,我注意到[NSOperation automaticallyNotifiesObserversForKey]类方法禁用了自动键值观察(NO至少返回某些键路径).因此,NSOperation子类中的代码通过手动调用来填充,willChangeValueForKey:并且didChange…在Web上的许多代码示例中都可见.
为什么这样NSOperation做?通过自动KVO支持,人们可以简单地声明操作生命周期标志(isExecuting等)的属性,并通过访问器触发KVO事件,即.以下代码:
[self willChangeValueForKey:@"isExecuting"];
executing = NO;
[self didChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];
finished = YES;
[self didChangeValueForKey:@"isFinished"];
Run Code Online (Sandbox Code Playgroud)
......可以替换为:
[self setIsExecuting:NO];
[self setIsFinished:YES];
Run Code Online (Sandbox Code Playgroud)
在某个地方有捕获吗?我只是覆盖了automaticallyNotifiesObserversForKey返回YES,事情似乎工作正常.
我有一个自定义NSManagedObject子类,比方说Person.我也UIView注册了-addObserver:forKeyPath:options:context:观察a的各种属性Person,其中一些像"名称"一样持久,而其他属性只是与Core Data无关的KVO兼容的访问器,如"喝酒".
@interface Person : NSManagedObject
{
BOOL drinking;
}
@property (nonatomic, retain) NSString* name;
@property (nonatomic, readonly) BOOL drinking;
@end
@implementation Person
@dynamic name;
...
- (void) getDrunk {
[self willChangeValueForKey: @"drinking"];
drinking = YES;
[self didChangeValueForKey: @"drinking"];
}
...
@end
Run Code Online (Sandbox Code Playgroud)
一切正常.每当我发送-getDrunk或设置name属性时,视图都会收到通知.我是一个快乐的人,除非我阅读以下NSManagedObject文件:
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
Run Code Online (Sandbox Code Playgroud)
事实1.如果接收器为键值提供键值观察变化通知的自动支持,则为YES,否则为NO.
事实2. NSManagedObject的默认实现为建模属性返回NO,为未建模属性返回YES.
现在我正在努力解析文档中的上述两个事实.检查事实2很简单,类人确实为@"name"返回NO,为@"drink"返回YES.但是,当名称发生变化时,视图如何得到通知?KVO文档清楚地说,
使用自动观察器通知时,没有必要通过调用willChangeValueForKey:和didChangeValueForKey来对属性进行更改:当通过键值编码和符合键值编码的方法改变属性时.
因此,如果Person从+automaticallyNotifiesObserversForKey:@"name" 返回NO ,那么我似乎必须手动将名称设置器包装will/didChangeValueForKey:为KVO才能工作.但是,KVO工作正常.我错过了什么?是什么在点NSManagedObject的覆盖+automaticallyNotifiesObserversForKey:和记录它,如果它似乎没有改变标准的志愿行为? …
我在Xcode的"Crashes"部分检索到以下崩溃日志时遇到了一些问题.此崩溃报告仅影响少数设备.
我已经分析了这个问题,但我猜这是Apple框架上的一个错误.但我找不到复制它的方法.
这里有类似的讨论:在removeObserver中帮助崩溃:forKeyPath : .
任何提示?
线程0名称:线程0崩溃:
0基础
0x23507591 _NSKeyValueReplaceObservationInfoForObject + 69(NSKeyValueObserving.m:1166)1基金会
0x23506fe7 - [NSObject(NSKeyValueObserverRegistration)_removeObserver:forProperty:] + 327(NSKeyValueObserving.m:1552)2基础
0x23506b03 - [NSObject(NSKeyValueObserverRegistration)removeObserver:forKeyPath:] + 163(NSKeyValueObserving.m:1696)3基础
0x235069a7 - [NSObject(NSKeyValueObserverRegistration)removeObserver:forKeyPath:context:] + 219(NSKeyValueObserving.m:1663)4 ApplicationName 0x0002e233 - [Supervisor removeObjectObserver:forKeyPath:] + 115(Supervisor.m:344)
这里removeObjectObserver:forKeyPath:是
- (void) removeObjectObserver:(id)object forKeyPath:(NSString *)keyPath {
@try {
[object removeObserver:self forKeyPath:keyPath context:PrivateKVOContext];
} @catch (NSException *exception) { }
}
Run Code Online (Sandbox Code Playgroud) 我试图观察UINavigationController的(readonly)visibileViewController属性但没有成功.我能够成功地观察到我自己定义的读写属性,以便在另一个类上进行测试.
是否有可能观察到readonly属性?
我在运行时在objective-c中有一个对象,我只知道KVC键,我需要检测此属性的返回值类型(例如,我需要知道它是NSArray还是NSMutableArray),我该怎么做呢?
在我的模型中,我有一个名为events的对象数组.我希望每当将新对象添加到事件时都会通知我的控制器.
我认为这样做的一个好方法是使用KVO模式在事件发生变化时收到通知(来自添加的新对象)
// AppDelegate
// events is a NSMutableArray @property/@synthesize etc...
[appDelagate addObserver:self
forKeyPath:@"events"
options:NSKeyValueObservingOptionNew
context:NULL];
Run Code Online (Sandbox Code Playgroud)
但是没有调用observeValueForKeyPath方法,我发现Arrays不符合KVO :-(
一种选择是通过为keyPath 调用willChangeValueForKey来手动触发该方法
// ViewController
[self willChangeValueForKey:@"events"];
[self.events addObject:event];
[self didChangeValueForKey:@"events"];
Run Code Online (Sandbox Code Playgroud)
但是这感觉很重,因为我应该跟踪事件数组的前后状态,以便可以从observeValueForKeyPath方法访问它.
一种方法可能是使用标准数组(而不是可变)并在每次我想要添加新对象时创建/设置新的事件实例,或者我可以创建一个单独的属性来跟踪有多少项在可变数组(我希望你能观察到@"events.count").
另一种选择是使用NSNotificationCenter.我还读了一些建议使用块的答案(但我不知道从哪里开始).
最后,我可以在我的代理中保留我的控制器实例并发送相关消息吗?
// Delegate
[myController eventsDidChange];
Run Code Online (Sandbox Code Playgroud)
从代表那里保持对控制器的引用是不是很奇怪?
我很难理解如何选择最佳使用方法,因此对性能,未来代码灵活性和最佳实践的任何建议都非常感谢!
model-view-controller delegates key-value-observing nsnotificationcenter ios
在Key-Value Observing Programming Guide中,注册键值观察部分说:"Apple提供的框架中的典型属性只有符合KVO标准才会被记录." 但是,我没有在文档中找到任何记录为KVO兼容的属性.你能指点一下吗?
具体来说,我想知道,如果@property(nonatomic,retain) UIViewController *rootViewController的UIWindow是国际志愿者组织兼容.原因是我正在为iOS <4 添加rootViewController属性,UIWindow并想知道我是否应该使其符合KVO标准.
@interface UIWindow (Additions)
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_4_0
@property (nonatomic, retain) UIViewController *rootViewController;
#endif;
@end
@implementation UIWindow (Additions)
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_4_0
@dynamic rootViewController;
- (void)setRootViewController:(UIViewController *)newRootViewController {
if (newRootViewController != _rootViewController) {
// Remove old views before adding the new one.
for (UIView *subview in [self subviews]) {
[subview removeFromSuperview];
}
[_rootViewController release];
_rootViewController = newRootViewController;
[_rootViewController retain]; …Run Code Online (Sandbox Code Playgroud) objective-c ×6
cocoa-touch ×3
iphone ×3
ios ×2
properties ×2
cocoa ×1
core-data ×1
crash ×1
delegates ×1
ios4 ×1
nsarray ×1
nsoperation ×1
runtime ×1
types ×1
uibutton ×1