是否可以在目标C中为静态变量设置KVO通知?

Ale*_*lex 6 design-patterns objective-c key-value-observing ios

我有A类,实例变量从缓存的数据派生属性,该缓存的数据表示为单例,并且是A的一部分(本质上是NSDictionary)。有时会修改此缓存。

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

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

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

换句话说,我很想拥有

static void* context = &context;
static myHadHocObject* msignal;
Run Code Online (Sandbox Code Playgroud)

然后在A类代码中

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

并通过通知类实例中的msignal更改

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

}
Run Code Online (Sandbox Code Playgroud)

我试过使用各种had hoc类,但是没有运气。似乎我缺少了一些东西。

指针是受欢迎的,谢谢!

por*_*lla 3

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

您可以从Apple 键值观察编程指南中获取回答问题所需的所有信息

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

- willChangeValueForKey:您可以使用和来触发 KVO - didChangeValueForKey:您可以在NSKeyValueObserving Protocol Reference中阅读更多相关内容

我建议您使用不同的方法,通过创建一个管理器来管理缓存并观察该缓存上的值,这只是一个示例。

缓存管理器.h

#import <Foundation/Foundation.h>

@interface CacheManager : NSObject

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

+ (instancetype)sharedManager;

@end
Run Code Online (Sandbox Code Playgroud)

缓存管理器.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
Run Code Online (Sandbox Code Playgroud)

视图控制器.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
Run Code Online (Sandbox Code Playgroud)

如果您从所有其他实例观察CacheManagerdata的属性,则当该属性发生更改时,所有该实例都会收到通知。

希望有帮助;)