在视图控制器之间传递参数时尤其需要注意“野指针”的问题。
因为程序总是在一个个视图控制器之间跳动,一些视图控制器所拥有的变量(跟UI相关),当视图跳转后,会被释放(出于节约iphone内存的考虑?)。
比如这样的代码:
在一个ViewController中:
RecipientRoll* controller=[[RecipientRoll alloc]initWithNibName:@"RecipientRoll" msgText:tvBill.text
expenseid:expense_id];
[self presentModalViewController:controller animated:YES];
注意红色字体部分,向另一个ViewController传递了一个字符串参数。但这个参数引用了本ViewController的UI控件属性。
随后以模式窗体的方式弹出另一个ViewController,此时第一个ViewController的UI会被释放。于是你传递的那个字符串内存被释放了,它的生命周期只有构造时候的短暂一小段时间,当模式窗体显示后它被释放了。如果你在此后还想用它做些什么,程序崩溃了,Xcode报告EXEC BAD。
因此我们需要利用它短暂的生命周期时间,对字符串做一个复制。在构造函数中这样写:
-(id)initWithNibName:(NSString *)nibNameOrNil msgText:(NSString*)d expenseid:(int)idx{
// NSLog(@"initWithNibName");
if (self=[super initWithNibName:nibNameOrNil bundle:nil]) {
expense_id=idx;
msgText=[[NSString alloc]initWithString:d];
//而不要这样写:msgText=d
}
return self;
}
这样,你可以放心地在这个ViewController被释放之前使用msgText变量了。