如何在初始化期间将值从 subclass 传递给 super class

How to pass value from subclass to super class during initialization

假设我有两个视图控制器。 ViewController1 是 ViewController2 的子 class。从 subclass (ViewController1),我调用了 superclass init 方法并通过参数传递了一个值并将该值分配给 superclass 变量。但是在 superclass (ViewController2) 的 viewDidLoad 方法中,该值始终为 null。为什么 ?我怎样才能将该值从 sub 传递到 super,以便我可以在 super class 的 viewDidLoad 方法中获取该值?

ViewController1.h

@interface ViewController : ViewController2

@end

ViewController1.m

@implementation ViewController

- (instancetype)init
{
    self = [super initWithName:@"Hello"];
    if (self) {
        NSLog(@"1  :");
    }
    return self;
}

- (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.
}

@end

ViewController2.h

@interface ViewController2 : UIViewController

@property (nonatomic, strong) NSString *name;
-(instancetype)initWithName:(NSString *)name;

@end

ViewController2.m

- (instancetype)initWithName:(NSString *)name
{
    self = [super init];

    if (self) {
        self.name = name;
    }

    return self;
}

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

    NSLog(@"2  : %@", self.name);

}

@end

更新 - 2016 年 3 月 16 日

示例:

ViewController1.h

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

@interface ViewController1 : ViewController2

@end

ViewController1.m

#import "ViewController1.h"

@interface ViewController1 ()

@end

@implementation ViewController1

-(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    //self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil andUserName:@"Ramesh Annadurai"];

    // we can use above init method or below method, both will work

    self = [super initWithName:@"Test Name"];

    if (self) {

        [self.view setBackgroundColor:[UIColor brownColor]];

    }

    return self;
}

-(instancetype)initWithCoder:(NSCoder *)aDecoder
{
//self = [super initWithCoder:aDecoder];

// If you are using storyboard use this initWithCoder method.

    self = [super initWithName:@"Test Name"];

    if (self) {

    }

    return self;
}

- (void)viewDidLoad {

    [super viewDidLoad];

}

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

}

@end

ViewController2.h

#import <UIKit/UIKit.h>

@interface ViewController2 : UIViewController

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil andUserName:(NSString *) userName;

- (instancetype)initWithName:(NSString *) userName;

@end

ViewController2.m

#import "ViewController2.h"

@interface ViewController2 ()

@property (strong, nonatomic) NSString *userName;

@end

@implementation ViewController2

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil andUserName:(NSString *) userName
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self) {

        self.userName = userName;

    }

    return self;

}

- (instancetype)initWithName:(NSString *) userName
{
    self = [super initWithNibName:nil bundle:nil];

    if (self) {

        self.userName = userName;

    }

    return self;
}

- (void)viewDidLoad {

    [super viewDidLoad];

    NSLog(@"User Name : %@", self.userName);

}

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

}

@end

我厌倦了你的代码,但它工作得很好。我怀疑您没有直接实例化 ViewController 。你在你的项目中使用故事板吗?如果是 - 您应该覆盖 ViewController 中的 initWithCoder:

但是,在 init-family 方法期间设置视图控制器的任何属性是个坏主意。根据 Apple 的建议,所有自定义都应在 -viewDidLoad-viewWill/DidAppear 方法中完成。

如果您绝对需要从外部设置 name 属性,最好直接赋值,而不是通过向 init 方法传递参数。

还有一件事 - initWithNibName:bundle:指定的初始化程序。这意味着,你的子类最终必须在初始化链中调用它。