如何使用KVO传递值?

时间:2017-08-11 18:12:26

标签: ios objective-c uistoryboardsegue key-value-observing kvc

我正在学习如何使用KVO。我创建了两个类,Truck和Driver,如下所示。

Truck类有一个文本字段和一个按钮,文本应该包含当前的卡车速度,当按下按钮时,应该调用prepareForSegue并且它包含下面发布的代码。

Driver类包含一个应该用卡车速度填充的文本字段。 Truck类中的卡车速度将通过KVO传递到Driver类中的文本字段,如代码所示。

我遇到的问题或我想要做的是,当用户在卡车类中输入卡车的速度并按下按钮时,我想显示在Driver类中通过文本字段输入的卡车速度KVO

根据下面发布的代码得到的结果是,Driver类中的空文本域

请让我知道为什么驱动程序类中的文本字段为空。以及如何通过KVO

将卡车速度的值从Truck类传递给Driver类

Truck.m

#import "TruckViewController.h"
#import "DriverViewController.h"
#import "ServerViewController.h"

@interface TruckViewController ()

@property (strong, nonatomic) IBOutlet UITextField *textFieldCurrenSpeed;
@property (strong, nonatomic) IBOutlet UIButton *buttonBroadcast;
@property (strong, nonatomic) IBOutlet UIButton 
*buttonToDriverViewController;
@property (strong, nonatomic) IBOutlet UIButton   
*buttonToServerViewController;
@property (strong, nonatomic) TruckViewController *truck;
@property (strong, nonatomic) DriverViewController *driver;
@property (strong, nonatomic) ServerViewController *server;

@end


@implementation TruckViewController


- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}


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


-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{
 self.truck = [[TruckViewController alloc] init];
 self.driver = [[DriverViewController alloc] init];
 self.server = [[ServerViewController alloc] init];

if ([segue.identifier isEqualToString:@"segueToDriver"]) {

    [self.truck addObserver:self.driver
            forKeyPath:@"currentSpeedOfTheTruck"
               options:NSKeyValueObservingOptionNew
               context:NULL];

    self.truck.currentSpeedOfTheTruck = [self.textFieldCurrenSpeed 
text];
    NSLog(@"prepareForSegue: %@", self.truck.currentSpeedOfTheTruck);
}

if ([segue.identifier isEqualToString:@"segueToServer"]) {

    [self.truck addObserver:self.server
            forKeyPath:@"currentSpeedOfTheTruck"
               options:NSKeyValueObservingOptionNew
               context:NULL];

    self.truck.currentSpeedOfTheTruck = [self.textFieldCurrenSpeed 
 text];
    NSLog(@"text entered: %@", self.truck.currentSpeedOfTheTruck);

 }

}

- (void)dealloc
{
[self.truck removeObserver:self.driver 
forKeyPath:@"currentSpeedOfTheTruck"];
[self.truck removeObserver:self.server    
forKeyPath:@"currentSpeedOfTheTruck"];
}

Driver.m

  #import "DriverViewController.h"

   @interface DriverViewController ()
   @property (strong, nonatomic) IBOutlet UITextField   
   *textFieldCurrentSpeed;

 @end


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

 if ([keyPath isEqualToString:@"currentSpeedOfTheTruck"]) {
    NSLog(@"DriverViewController->currentSpeedOfTheTruck: %@",
          [object valueForKey:keyPath]);

    NSLog(@"DriverViewController->currentSpeedOfTheTruck: %@",
          [change objectForKey:NSKeyValueChangeNewKey]);

    self.receivedCurrentSpeed = [change   
 objectForKey:NSKeyValueChangeNewKey];
    [self.textFieldCurrentSpeed setText:self.receivedCurrentSpeed];

 }
 }



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

   NSLog(@"DriverViewController->viewDidLoad");

   [self.textFieldCurrentSpeed setText:self.receivedCurrentSpeed];
   }

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

日志输出

2017-08-13 19:53:55.293 KVC-1[91529:2346883] DriverViewController-  
>currentSpeedOfTheTruck: 45

2017-08-13 19:53:55.294 KVC-1[91529:2346883] DriverViewController- 
>currentSpeedOfTheTruck: 45
2017-08-13 19:53:55.294 KVC-1[91529:2346883] prepareForSegue: 45

1 个答案:

答案 0 :(得分:3)

问题在于这些代码行

 self.truck = [[TruckViewController alloc] init];
 self.driver = [[DriverViewController alloc] init];
 self.server = [[ServerViewController alloc] init];

由于您在准备segue之前创建了另一个对象而不是一个对象,因此您应该使用segue.destinationController来传输值

将上面的代码行更改为

 self.truck = (TruckViewController *) segue.destinationViewController;

相对于所有的viewcontrollers。