如何在初始化期间将值从子类传递给超类

时间:2016-03-15 08:30:10

标签: ios objective-c oop inheritance superclass

假设,我有两个视图控制器。 ViewController1是ViewController2的子类。从子类(ViewController1),我调用了超类init方法&通过参数&传递值将该值赋给超类变量。但是在超类(ViewController2)的viewDidLoad方法中,该值始终为null。为什么?如何将该值从sub传递给super,以便我可以在超类的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

2 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:0)

更新 - 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