标签: key-value-observing

使用NSArray观察关键值

我已经在SO上查看了使用键值观察的示例NSArray(或者NSMutableArray),显然你需要使用NSArrayController(不像KVO我不熟悉的),但我没有找到如何执行此操作的具体示例.有人可以解释一些示例代码吗?

例如,如果我有一个GameModel代表其播放器名称NSArray (playerNameArray)的a NSStrings.我想观察那些字符串(视图控制器观察模型的数据)来更新视图中的各种内容.

如何获得播放器名称数组已更改的通知?

编辑:iOS SDK甚至支持NSArrayController吗?如果没有,还有另一种方式吗?

iphone objective-c key-value-observing nsarray nsarraycontroller

21
推荐指数
1
解决办法
1万
查看次数

"收到的消息但未处理"KVO

运行项目时,我在输出窗口中收到以下内容:

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事件被解雇时采取"测试".

随着消息一直进入,堆栈跟踪变得非常快.但似乎一切都运转正常.

有线索吗?

objective-c key-value-observing

21
推荐指数
3
解决办法
1万
查看次数

如何倾听UIButton状态的变化?

我正在扩展UIButton通用功能,以根据显示的标题更改某些外观属性.

为此,我需要检测并响应"state"属性的变化.这样,如果用户为不同的状态设置了不同的标题,我确保正确调整外观.我以为我需要使用某种KVO,如下所示:

[self addObserver:self 
       forKeyPath:@"state" 
          options:NSKeyValueObservingOptionNew 
          context:nil];
Run Code Online (Sandbox Code Playgroud)

但这似乎没有触发@"state"或@"currentTitle"的observeValueForKeyPath:...方法.我假设这是因为UIButton没有为这些属性实现KVO模式.

我不想只听点击.这些事件导致状态改变,但不是唯一的潜在原因.

有没有人知道如何倾听和回应UIButton的状态变化?

谢谢


UPDATE

因为我在过去几年中学到了一些东西,所以只是一个注释;).

我已经和一些知道的苹果人谈过了,而且KVO没有在国家财产上工作的原因是因为UIKit的NONE肯定是符合KVO的.在这里值得重复的思考 - 如果你试图听取UIKit框架类的任何属性,请注意它可能有效,但是没有得到官方支持,可能会在不同的iOS版本上中断.

iphone cocoa-touch objective-c key-value-observing uibutton

20
推荐指数
2
解决办法
2万
查看次数

为什么NSOperation会禁用自动键值观察?

使用自定义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,事情似乎工作正常.

key-value-observing nsoperation

20
推荐指数
2
解决办法
4197
查看次数

NSManagedObject和KVO vs Documentation

我有一个自定义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:和记录它,如果它似乎没有改变标准的志愿行为? …

cocoa core-data key-value-observing nsmanagedobject

20
推荐指数
1
解决办法
4818
查看次数

使用removeObserver崩溃:forKeyPath:在Foundation中

我在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)

crash objective-c key-value-observing

20
推荐指数
2
解决办法
6350
查看次数

是否可以在Cocoa Touch中观察对象的只读属性?

我试图观察UINavigationController的(readonly)visibileViewController属性但没有成功.我能够成功地观察到我自己定义的读写属性,以便在另一个类上进行测试.

是否有可能观察到readonly属性?

iphone cocoa-touch properties key-value-observing

19
推荐指数
3
解决办法
5511
查看次数

如何在Objective-C中检测属性返回类型

我在运行时在objective-c中有一个对象,我只知道KVC键,我需要检测此属性的返回值类型(例如,我需要知道它是NSArray还是NSM​​utableArray),我该怎么做呢?

types runtime properties objective-c key-value-observing

19
推荐指数
2
解决办法
2万
查看次数

使用KVO与NSNotificationCenter观察对可变阵列的更改

在我的模型中,我有一个名为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

19
推荐指数
1
解决办法
2万
查看次数

iOS:我如何知道某个属性是否符合KVO标准?

Key-Value Observing Programming Guide中,注册键值观察部分说:"Apple提供的框架中的典型属性只有符合KVO标准才会被记录." 但是,我没有在文档中找到任何记录为KVO兼容的属性.你能指点一下吗?

具体来说,我想知道,如果@property(nonatomic,retain) UIViewController *rootViewControllerUIWindow是国际志愿者组织兼容.原因是我正在为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)

cocoa-touch objective-c key-value-observing ios4 ios

18
推荐指数
1
解决办法
6656
查看次数