如何访问动态传递给iOS中的子视图控制器的参数?

时间:2012-12-16 06:03:19

标签: ios inheritance uiviewcontroller

我有一个viewController,它有一个按钮,当点击该按钮时,会动态创建对另一个viewController类的引用,并在此过程中设置该viewController的参数。我在for循环中执行此操作,如下所示:

-(void) clickOnButton:(id)sender {


    for (PersonObject *checkPerson in [DataModel sharedInstance].personList) {

        if (((UIControl*)sender).tag == checkPerson.personID) {

            ParentViewController *parentView = [[NSClassFromString(checkPerson.childViewController) alloc] init];
            parentView.personName = checkPerson.name;
            NSLog(parentView.personName);
            [self.navigationController pushViewController:parentView animated:YES];


        }

    }

}

在创建的viewController中以及用户被发送到的viewController中,我在viewDidLoad方法中有以下代码:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    NSLog(@"Hello %@", personName);
    UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(0, 10, 150, 35)];
    [title setCenter:CGPointMake(self.view.frame.size.width/2, 27)];
    [title setBackgroundColor:[UIColor clearColor]];
    [title setTextAlignment:NSTextAlignmentCenter];
    [title setFont:[UIFont boldSystemFontOfSize:15]];
    [title setText:personName];
    [self.view addSubview:title];

}

当我运行我的代码时,第一个viewController给我正确输出到personName参数的NSLog,但是,第二个viewController语句中方法viewDidLoad中的NSLog()显示我的personName值是nil,并且没有任何东西显示为viewController的标题。

参数personName的类型为NSString,可以在父viewController类中找到,也可以在子viewController类中找到(有几个viewController类正在扩展这一个父类)。如何动态创建子viewController对象,并让它捕获使用父viewController发送给它的正确参数值?

1 个答案:

答案 0 :(得分:1)

一个常见的错误是在您要转换到的视图控制器中有一个接口,如:

@interface MyViewController : UIViewController
{
    NSString *personName;
}
@property (nonatomic, retain) NSString *personName
@end

然后是一个未明确合成personName的实现或具有@synthesize语句的实现,如:

@implementation MyViewController

@synthesize personName = _personName;

// the rest of the implementation

@end

注意,如果您没有明确声明的@synthesize语句,它将自动合成personName,就像上面的语句一样。

这个相当无害的代码是有问题的,因为你最终会得到两个实例变量,一个名为personName,另一个名为_personName,它是为你合成的,被称​​为{ {1}}。

你真正应该做的是消除明确声明的ivar,因此@interface看起来像:

@interface MyViewController : UIViewController
@property (nonatomic, retain) NSString *personName
@end

然后要么完全省略@synthesize语句,要么省略一个:

@synthesize personName = _personName;

然后,您的代码可以通过其访问器引用该属性,例如

NSLog(@"Hello %@", self.personName);

或者您可以使用实例变量(ivar):

NSLog(@"Hello %@", _personName);

(顺便说一下,通常建议在setting properties时使用访问者(例如self.personName)。唯一真正必须使用ivar(例如_personName)的是initializer methods and dealloc。)

但是,底线,不要显式定义实例变量,让编译器为你合成它,消除这种问题。并且建议将ivar与前导下划线合成,以便在您真正打算使用该属性的存取方法时尽量减少对ivar的意外使用。

有关详细信息,请参阅高级内存管理编程指南中的Practical Memory Management