在 Objective C 中切换视图控制器时返回空值的变量

variables returning null value upon switching View Controllers in Objective C

我是 objective C 编程的新手,正在研究在视图控制器之间移动数据。我想知道 ViewController 之间的双向数据流(变量)是否可能。 我可以向后移动数据(到 presentingViewController / sourceViewController)但是我不能向前移动数据(到 presentedViewController / destinationViewController)。

我做了一个简单的案例场景(涉及字符串以获得想法的原理),它涉及使用 [=36= 在 destinationViewController 上更新 UItextField ]UILabel 在 sourceViewController 中,反之亦然。 我无法使用 UILabel 更新 UITextField,但可以使用 更新 UILabel ]UITextField。 我已经制作了不同语句的日志来跟踪变量值,但是当我将 ViewControllers 变量 Data returns 切换为 null 时,即使它们被标记为 strong.

能否请您提供任何指导,它一直在撕裂我的脑海,还是我遗漏了一些明显的东西?我不明白为什么当我切换 ViewControllers 时我总是得到一个(空)值(在我的 NSLog 中)。

我在下面附上了我的代码文件:

ViewController.h:

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet UILabel *outputLabel;
- (IBAction)ExitToHere:(UIStoryboardSegue *)sender;
@end

ViewController.m:

#import "ViewController.h"
#import "Gear2ViewController.h"

@interface ViewController ()
- (IBAction)changeItem:(id)sender;
@end

@implementation ViewController

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

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

- (IBAction)changeItem:(id)sender {

    Gear2ViewController *G2VC=[[Gear2ViewController alloc] init];

    G2VC.peterSido=[NSString stringWithFormat:@"%@",self.outputLabel.text];

    [self performSegueWithIdentifier:@"toGear2" sender:self];

    NSLog(@"ViewController UILabel reads %@",G2VC.peterSido);
}

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
}

- (IBAction)ExitToHere:(UIStoryboardSegue *)sender {
}

@end

战争机器2ViewController.h:

#import <UIKit/UIKit.h>
#import "ViewController.h"

@interface Gear2ViewController : UIViewController
@property (strong, nonatomic) NSString *peterSido;
@end

战争机器2ViewController.m:

@interface Gear2ViewController ()
@property (strong, nonatomic) IBOutlet UITextField *updatedOutput;
- (IBAction)updateOutput:(id)sender;
@end

@implementation Gear2ViewController


- (void)viewDidAppear:(BOOL)animated {

    [super viewDidAppear:animated];
    NSLog(@"Gears2ViewController ViewDidAppear reads %@",self.peterSido);
}

- (void)viewDidLoad {

    [super viewDidLoad];
    NSLog(@"Gears2ViewController ViewDidLoad responds %@",self.peterSido);
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)updateOutput:(id)sender {

    self.peterSido = self.updatedOutput.text;
    ((ViewController *)self.presentingViewController).outputLabel.text = self.peterSido;
     NSLog(@"Gears2View Controller updating ViewController UILabel reads %@",self.peterSido);  
}

@end

NSLog:

2015-06-29 18:52:58.798 testerBeta[21735:645772] Gears2ViewController ViewDidLoad responds (null)
2015-06-29 18:52:58.799 testerBeta[21735:645772] ViewController UILabel reads I like Pie
2015-06-29 18:52:59.317 testerBeta[21735:645772] Gears2ViewController ViewDidAppear reads (null)
2015-06-29 18:53:12.651 testerBeta[21735:645772] Gears2View Controller updating ViewController UILabel reads No I dont

很长但提前致谢!!!

你想传递prepareForSegue:中的数据,像这样:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)__unused sender
{
    if ([[segue identifier] isEqualToString:@"toGear2"])
    {
        Gear2ViewController *controller = (Gear2ViewController *)segue.destinationViewController;
        controller.peterSido = self.outputLabel.text;
    }
}

原因是 segue 为您实例化呈现的视图控制器,然后您设置 segue 将呈现的实例化视图控制器的 属性。

要传回数据,您可以使用 unwind segue,它可以从呈现的视图控制器的 属性.

中获取值
- (IBAction)unwindFromGear2:(UIStoryboardSegue *)segue
{
    Gear2ViewController *controller = (Gear2ViewController *)segue.sourceViewController;
    self.outputLabel.text = controller.peterSido;
}

这是通过 segues 来回传递数据的正确方法。 Gear2ViewController 不应该 在其 presentingViewController 上设置属性。

更新:

测试 属性 不是 nil 的首选方法是这样的:

if (self.peterSido)
{
    self.updatedOutput.text = self.peterSido;
}
else // No need for if test here
{
    self.updatedOutput.text = @"";
}

这是长格式,但赋值和 if 测试可以更简洁地写成:

self.updatedOutput.text = self.peterSido ?: @"";

当您将任何变量声明为@属性 时,您需要将其合成到.m 文件中。 您已将 outputLabel 声明为 @属性 但您错过了在 .m 文件中合成它。 当您合成任何变量时,它允许您获取和设置它的值。 去做对你有帮助。

谢谢。