弹出当前视图时,将NSString传递并保留到另一个视图

时间:2012-01-04 20:36:35

标签: ios

我有一个方法会解除导航控制器中的当前视图并将其替换为另一个视图。代码看起来像这样

-(void)didTransferRequest:(NSString *)_transferComments {

    AddRequestViewController *ar = [[AddRequestViewController alloc]
             initAsTransferForRequestID:requestID 
             withClosingComments: _transferComments]];

    UINavigationController *currentNav = self.navigationController;

    [[self retain] autorelease];

    [currentNav popViewControllerAnimated:NO];
    [currentNav pushViewController:ar animated:NO];

    [ar release];

}

[AddRequestViewController.m]

-(AddRequestViewController *)initAsTransferForRequestID:(int)requestID 
                            withClosingComments:(NSString *)closingComments{
    self = [self initWithStyle:  UITableViewStyleGrouped];

    if (self) {
       _requestID = requestID;
       _closingComments = closingComments;
    }

    return self;
}

问题是,一旦将新视图推送到导航堆栈,当视图尝试访问_transferComments传入的内容时,它会崩溃。指针指向其他一些因为视图弹出而有意义的东西。

我成功使用了withTransferComments:[_ transferFotes copy]但是分析器用这个确定了内存泄漏。

使用copy是否安全,我应该忽略泄漏消息还是有更好的方法来发送字符串?

1 个答案:

答案 0 :(得分:0)

您的AddRequestViewController未取得_transferComments的所有权。

您需要阅读Cocoa Core Competencies - Memory ManagementBasic Memory Management Rules

在您发布的代码段中(没有副本),我推断AddRequestViewController未向retain发送_transferComments。如果要确保_transferComments保持不变,则需要向其发送retain消息以获取字符串的所有权。当AddRequestViewController完成字符串后,需要发送它release以放弃所有权。您可能会在-[AddRequestViewController dealloc]中执行此操作。

基本上,您的initAsTransferForRequestID:withClosingComments:方法应如下所示:

- (id)initAsTransferForRequestID:(int)requestId withClosingComments:(NSString *)transferComments {
    if (!(self = [super init]))
        return nil;

    _requestId = requestId;
    _transferComments = [transferComments retain];

    return self;
}

(请注意,我使用的是使用前导下划线命名实例变量的通用约定。)您的dealloc方法应如下所示:

- (void)dealloc {
    [_transferComments release];
    [super dealloc];
}

当您更改代码以复制_transferRequest时,您确实创建了内存泄漏。 copy消息创建了对该副本的“拥有”引用,并且需要对放弃该所有权负责。您没有更改任何一个对象来执行此操作。