ios 简单的 KVO 示例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24969523/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:34:17  来源:igfitidea点击:

Simple KVO example

iosobjective-ckey-value-observing

提问by WebOrCode

I am trying to do simple KVO example, but I am having problems.

我正在尝试做简单的 KVO 示例,但我遇到了问题。

This is my *.m file:

这是我的 *.m 文件:

#import "KVO_ViewController.h"

@interface KVO_ViewController ()

@property NSUInteger number;

@end

@implementation KVO_ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [self addObserver:self forKeyPath:@"number" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)incNumber:(id)sender
{
    _number++;
    NSLog(@"%d", _number);
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"From KVO");

    if([keyPath isEqualToString:@"number"])
    {
        id oldC = [change objectForKey:NSKeyValueChangeOldKey];
        id newC = [change objectForKey:NSKeyValueChangeNewKey];

        NSLog(@"%@ %@", oldC, newC);
    }
}

@end

Note:I have a button which when clicked it will increment the numberproperty.
I want to be notified when numberproperty is changed.

注意:我有一个按钮,单击它会增加number属性。
我想在number属性更改时收到通知。

The code is not working and I can not figure it why.

代码不起作用,我不知道为什么。

采纳答案by codester

KVO works with setter and getter and in incNumberyou are directly accessing iVar so instead of that use self.number

KVO 与 setter 和 getter 一起使用,并且incNumber您直接访问 iVar,而不是使用self.number

- (IBAction)incNumber:(id)sender
{
    self.number++;
    NSLog(@"%d", self.number);
}

回答by Abizern

Rather than:

而不是:

_number++;

Try:

尝试:

[self willChangeValueForKey:@"number"];
_number++;
[self didChangeValueForKey:@"number"];

or ever better just:

或者更好的是:

self.number++

And let the system take care of the willChangeValueForKey:and didChangeValueForKey:methods.

并让系统照顾willChangeValueForKey:didChangeValueForKey:方法。

回答by parvind

@interface TraineeLocationCell : UIView
@property (strong, nonatomic) NSString *traineeAddress;
@end

@implementation

// in textview delgate method  i am setting traineeAddress string value
- (void)textViewDidEndEditing:(UITextView *)textView
{
    if (textView.text.length >0)
    [self setValue:textView.text forKey:@"traineeAddress"];

}

@end

and in other class where i am using this class

在我使用这个课程的其他课程中

 TraineeLocationCell *locationView;//create object here
 [locationView addObserver:self forKeyPath:@"traineeAddress" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];//observing the key in this class

//this is the delegate method which take care of value is changed or not

//这是处理值是否改变的委托方法

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
   if([keyPath isEqualToString:@"traineeAddress"]){
        if (!settingsValues.address)
            settingsValues.address = [[NSMutableArray alloc]initWithObjects:[change valueForKey:@"new"], nil];

        else
            [settingsValues.address replaceObjectAtIndex:0 withObject:[change valueForKey:@"new"]];
    }
}