2012-03-29 58 views
2

这是我的方法之一。如何释放保留对象的内存

- (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]; 
} 

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

[_dataProvider startGettingSearchResultsByKeyword:self.searchKeyword 
             searchOptions:_searchOptions 
           searchGroupsInResult:_searchGroupsInResult 
               pageNo:_pageNo 
              delegate:self]; 

调用。 ([keyword release][_searchKeyword release])??

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

我跑分析工具,它并没有显示这个问题。但我对此持怀疑态度。

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

我正在使用XCode4和iOS 4.3。

谢谢。

+0

你用'[object_address release]'释放一个对象。 – 2012-03-29 16:32:08

回答

2

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

所以,在你的.h(或者在你的类扩展中。米若的属性应该是 “私有”):

@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文档。

0

当有两个对象是指向同一事物的对象时,无论您呼叫哪个释放对象。指出的是引用计数减少的地方。

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

2

既然你是分配到伊娃,你必须保留它。这是对的。 在dealloc中释放它也是正确的。但那还不够。两件事:

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

2)当你第二次调用你的方法时,还有一个问题。这是关键,你确实有泄漏。您正在给您的ivar`_searchKeyword'分配一个新的值,解散指向旧关键字的指针,该关键字仍然保留。所以在分配新的之前,也要释放旧的。

例子:

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

如果你把它复制,这是件好事,但如果你只保留,这将是更好的做这样的(如果都引用同一个对象):

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

thanx jaydee3。你的答案是绝对有用的。但我还有一个问题。当第一次调用'-getSearchResultsByKeyword:searchOptions:searchGroupsInResult:'方法时,'_searchKeyword'的保留计数为0.所以在'[_searchKeyword release]'调用之后,会发生什么? – chinthakad 2012-03-29 17:04:49

+2

绝对保留数是毫无意义的; 'copy'的结果是+1保留计数。实际保留数可能大不相同。 – bbum 2012-03-29 17:10:49

+0

不幸的是,@ bbum,有一个doc引用人引用复制对象的保留计数的错误:“复制对象不仅复制它,而且几乎总是将其保留计数重置为一个”[“内存管理如何工作”] (http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW10),正如可可粉图2.5所示基本面。 – 2012-03-29 18:20:46