0

我有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 中,我的 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 发送给它的正确参数值?

4

1 回答 1

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.

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

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

然后要么完全省略该@synthesize语句,要么有一个看起来像这样的语句:

@synthesize personName = _personName;

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

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

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

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

(顺便说一句,通常建议在设置属性self.personName时使用访问器(例如)。您真正必须使用 ivar(例如)的唯一时间是在初始化方法和 dealloc中。)_personName

但是,最重要的是,不要显式定义实例变量,让编译器为您合成它,从而消除此类问题。建议将 ivar 与前导下划线合成,以尽量减少在您真正打算使用属性的访问器方法时意外使用 ivar。

有关详细信息,请参阅Advanced Memory Management Programming Guide中的Practical Memory Management

于 2012-12-16T06:28:59.450 回答