如何释放保留对象的内存

时间:2012-03-29 14:10:58

标签: objective-c ios memory-management xcode4 memory-leaks

这是我的方法之一。

- (void)getSearchResultsByKeyword:(NSString *)keyword 
                searchOptions:(NSArray *)searchOptions 
         searchGroupsInResult:(NSArray *)searchGroupsInResult
{
    _searchKeyword = [keyword retain];
    _searchOptions = [searchOptions retain];
    _searchGroupsInResult = [searchGroupsInResult retain];
    [_searchResultsGroups removeAllObjects];
    [_searchResultsGroupsIndexToNameMap removeAllObjects];
    _pageNo = 1;
    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:SearchResultsRetrievingStartLodingNotification 
                                                                object:self];
    [_dataProvider startGettingSearchResultsByKeyword:self.searchKeyword 
                                    searchOptions:_searchOptions
                             searchGroupsInResult:_searchGroupsInResult
                                           pageNo:_pageNo
                                         delegate:self];
}

在我的方法中,我在对象上调用了retain,这些对象是参数。所以我拥有了该对象并增加了保留计数。所以我的问题是,如何在

之后减少保留计数
[_dataProvider startGettingSearchResultsByKeyword:self.searchKeyword 
                                        searchOptions:_searchOptions
                                 searchGroupsInResult:_searchGroupsInResult
                                               pageNo:_pageNo
                                             delegate:self];

呼叫。 ([keyword release][_searchKeyword release])??

在我的头文件中,我已将_searchOptions声明为私有实例,将_searchKeyword声明为readonly属性。在我的实现文件中,我已在dealloc中发布了这两个实例。

我运行了Analyze工具,并没有将此事显示为问题。但我对它有疑问。

所以,请告诉我一个必要的方法来处理这件事。

我正在研究XCode4和iOS 4.3。

感谢。

3 个答案:

答案 0 :(得分:2)

由于您要分配给ivar,您必须保留它。这是对的。 在dealloc中释放它也是正确的。但那还不够。两件事:

1)最好复制字符串,而不是保留它们。所以使用_searchKeyword = [keyword copy];。 (这也是保留的。所以之后retainCount是1。)

2)当您第二次调用方法时,也会出现问题。这就是你确实有泄漏的地方。您正在为您的ivar`_searchKeyword'分配一个新值,忽略指向仍保留的旧关键字的指针。所以在分配新的之前,也要发布旧版本。

示例:

[_searchKeyword release];
_searchKeyword = [keyword copy];

如果你复制它,这很好,但是如果你只保留,那么这样做会更好(如果它们都引用同一个对象):

[keyword retain];
[_searchKeyword release];
_searchKeyword = keyword;

答案 1 :(得分:2)

jaydee3的回答是正确的。我想补充一点,真的应该使用带有合成访问器的@properties。然后,不使用直接设置实例变量,而是使用访问器方法。这样,您可以在访问器方法中封装实例变量的所有内存管理。这样做的好处是更易读,更不容易出错,并且使您的代码在将来更容易修改。

所以,在你的.h(或.m的类扩展中,如果属性应该是“私有的”):

@property (nonatomic, copy) NSString *searchKeyword;

在你的.m:

- (void)dealloc
{
    self.searchKeyword = nil;

    [super dealloc];
}

@synthesize searchKeyword = _searchKeyword;

最后,在您的-getSearchResultsByKeyword:searchOptions:searchGroupsInResult:方法中:

self.searchKeyword = keyword;

而不是

_searchKeyword = [keyword retain];

现在您不必担心发布保留searchKeyword。 @synthesize指令生成的setter方法将为您处理。我建议在Declared Properties上阅读Apple的文档。

答案 2 :(得分:0)

当有两个对象指向同一个东西时,你调用哪个对象并不重要。指向的是引用计数递减的位置。

鉴于你已经在一个地方发布了它,并且分析仪没有抱怨,你没有问题。