可以在客观C中为静态变量设置KVO通知吗? [英] Is it possible to set up KVO notifications for static variables in objective C?

查看:171
本文介绍了可以在客观C中为静态变量设置KVO通知吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类A,实例变量从缓存数据中导出属性,这个缓存数据被表示为一个单例,并且是A的一部分(它本质上是一个NSDictionary)。有时,这个缓存被修改。



发生这种情况时,我希望所有A实例在下次访问其属性时从缓存中提取新信息,或者换句话说,使其属性内容无效。



到目前为止,每个实例都被手动通知(使用静态数组跟踪成员)。我不是粉丝有可能是通知中心的选项,但我宁愿尝试使用KVO。



有没有人曾经设法从iOS上的类变量订阅KVO更改? (换句话说,使用A的静态变量的变化来告诉A实例来刷新他们的数据。)



在其他语言中,我希望拥有

p>

  static void * context =& context; 
static myHadHocObject * msignal;

及以后的A类代码

  [msignal addObserver:self forKeyPath:@operationoptions:NSKeyValueObservingOptionNew context:context]; 

,并通过


$ b通知课程实例中的msignal更改$ {pre> - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)更改上下文:(void *)context {

}

我试图使用各种非特殊类,没有运气。



指针是欢迎的,谢谢!

解决方案

KVO表示特定对象观察另一个对象(或其自身)的属性上的更改。所以我想你想要实现的是不可能的,至少不是这样的。或者至少你需要更深入地了解KVO机制。



您可以从



(可选)/ $ / $ / $ / $


与使用NSNotificationCenter的通知不同,没有
中心对象为所有观察者提供更改通知。
相反,当
更改时,通知将直接发送到观察对象。 NSObject提供了
键值观察的基础实现,您很少需要覆盖这些
方法。


您可以使用 - willChangeValueForKey: - didChangeValueForKey:启动KVO。您可以在 NSKeyValueObserving Protocol Reference



我建议您使用其他方法,通过创建一个管理器来管理缓存,并观察该缓存上的值,仅举一个例子。 >

CacheManager.h

  #import<基金会/ Foundation.h> 

@interface CacheManager:NSObject

@property(nonatomic,strong,readonly)NSArray * data;

+(instancetype)sharedManager;

@end

CacheManager.m / p>

  #importCacheManager.h

@implementation CacheManager

- (instancetype)init {
if(self = [super init]){
_data = [[NSArray alloc] init];
}

return self;
}

+(instancetype)sharedManager {
static CacheManager * selfManager;

static dispatch_once_t onceToken;
dispatch_once(& onceToken,^ {
selfManager = [[[self class] alloc] init];
});

return selfManager;
}

@end

ViewController.m

  #importViewController.h

#importCacheManager.h

static void * CacheManagerDataChangedContext =& CacheManagerDataChangedContext;

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

CacheManager * cacheManager = [CacheManager sharedManager];

[cacheManager addObserver:self forKeyPath:NSStringFromSelector(@selector(data))选项:NSKeyValueObservingOptionNew上下文:CacheManagerDataChangedContext];
}

- (void)dealloc {
[[CacheManager sharedManager] removeObserver:self forKeyPath:NSStringFromSelector(@selector(data))context:CacheManagerDataChangedContext]


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

if(context == CacheManagerDataChangedContext){
<#你的东西#>
}

else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}

@end

如果您观察所有其他实例的 CacheManager 数据属性,所有该实例将在此更改时收到通知。



希望有帮助;)


I have class A, with instance variables deriving attributes from cached data, this cached data is represented as a singleton and is part of A (it's essentially a NSDictionary). From time to time, this cache is modified.

When this happens, I would like to have all A instances pull new information from the cache the next time they access their attribute , or in other words, invalidate their attribute content.

Up to now, each instances is notified manually (using a static array to track members). I'm not a fan. There's might be an option with notification centre, but I'd rather try with KVO.

Has anyone ever managed to subscribe to KVO changes from a class variable on iOS ? (in other words, use changes from a static variable of A to tell A-instances to refresh their data.)

in otherwords, I'd love to have

static void* context = &context;
static myHadHocObject* msignal;

and later in Class A code

[msignal addObserver:self forKeyPath:@"operation" options:NSKeyValueObservingOptionNew context:context];

and be notified of msignal changes in a class instance via

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

}

I've tried to use various had hoc classes, with no luck. Seems I'm missing something.

pointers are welcome, thanks !

解决方案

KVO says that a specific object observes changes on a property of another object (or itself). So i think what you're trying to achieve is not possible, at least not like this. Or at least you need to go deeper on the KVO mechanism.

You can get all information you need to answer your question from Apple Key-Value Observing Programming Guide

Unlike notifications that use NSNotificationCenter, there is no central object that provides change notification for all observers. Instead, notifications are sent directly to the observing objects when changes are made. NSObject provides this base implementation of key-value observing, and you should rarely need to override these methods.

You can fire KVO, with - willChangeValueForKey: and - didChangeValueForKey:. You can read more about this at NSKeyValueObserving Protocol Reference

I suggest that you use a different approach, by creating a manager to manage your cache with and observe the values on that cache, just an example.

CacheManager.h

#import <Foundation/Foundation.h>

@interface CacheManager : NSObject

@property (nonatomic, strong, readonly) NSArray *data;

+ (instancetype)sharedManager;

@end

CacheManager.m

#import "CacheManager.h"

@implementation CacheManager

- (instancetype)init {
    if (self = [super init]) {
        _data = [[NSArray alloc] init];
    }

    return self;
}

+ (instancetype)sharedManager {
    static CacheManager *selfManager;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        selfManager = [[[self class] alloc] init];
    });

    return selfManager;
}

@end

ViewController.m

#import "ViewController.h"

#import "CacheManager.h"

static void *CacheManagerDataChangedContext = &CacheManagerDataChangedContext;

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    CacheManager *cacheManager = [CacheManager sharedManager];

    [cacheManager addObserver:self forKeyPath:NSStringFromSelector(@selector(data)) options:NSKeyValueObservingOptionNew context:CacheManagerDataChangedContext];
}

- (void)dealloc {
    [[CacheManager sharedManager] removeObserver:self forKeyPath:NSStringFromSelector(@selector(data)) context:CacheManagerDataChangedContext];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    if (context == CacheManagerDataChangedContext) {
        <# your stuff #>
    }

    else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

@end

If you observe the data property of CacheManager from all the other instances, all that instance will get notified when that changes.

Hope that helps ;)

这篇关于可以在客观C中为静态变量设置KVO通知吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆