假设,我有两个视图控制器。 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
答案 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