代码改变世界

OC内存管理

2011-01-20 17:54  乱世文章  阅读(281)  评论(0编辑  收藏  举报

在视图控制器之间传递参数时尤其需要注意“野指针”的问题。

因为程序总是在一个个视图控制器之间跳动,一些视图控制器所拥有的变量(跟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变量了。