Ios 指向框架中泄漏的仪器——发现泄漏在其他地方(为什么?)
我越来越熟悉用于调试的工具,而且它比最初看起来更容易使用。发布这个问题是为了让我理解为什么它指向一行代码作为我的泄漏源,以及解决它的逻辑过程是什么 这个答案可能会让其他尝试使用仪器的人受益。我还没有看到很多关于如何使用它的细节。(这里有《仪器用户指南》,这是一个良好的开端,但仅此而已。) 在本例中,Instruments指向从SBJSON框架返回JSONValue(类型NSDictionary)的线路上的一个可重复泄漏。我尝试了各种方法来隔离问题(见下文),在每种情况下,工具都指向返回JSON dictionary对象的行 我尝试的另一件事是iOS 5中提供的NSJSONSerializer。仪器再次指向同一条线。显然,仪器误导了我(为什么?我能做些什么来避免/改善这种情况? 长话短说,问题不在于仪器指向何处,而是在包含该行的实例中。在本例中,有两个属性没有被释放,它们的值是从反序列化的JSON字典派生的 我通过反复试验、注释代码并用文本字符串替换返回值,得出了这个结论。(如果我吓了你一跳,我很抱歉,斯蒂格!)Ios 指向框架中泄漏的仪器——发现泄漏在其他地方(为什么?),ios,memory-management,memory-leaks,instruments,Ios,Memory Management,Memory Leaks,Instruments,我越来越熟悉用于调试的工具,而且它比最初看起来更容易使用。发布这个问题是为了让我理解为什么它指向一行代码作为我的泄漏源,以及解决它的逻辑过程是什么 这个答案可能会让其他尝试使用仪器的人受益。我还没有看到很多关于如何使用它的细节。(这里有《仪器用户指南》,这是一个良好的开端,但仅此而已。) 在本例中,Instruments指向从SBJSON框架返回JSONValue(类型NSDictionary)的线路上的一个可重复泄漏。我尝试了各种方法来隔离问题(见下文),在每种情况下,工具都指向返回JSON
早期更新 这是我的帖子的修订版。我相信我已经将问题缩小到了SBJSON返回字符串未自动删除的故障。我想知道我的消除过程是否有意义,我应该做出什么结论,以及如何解决这个问题 原来的问题在下面。我将重点放在以下代码上:
NSString *resultsGeocodeLiteralString = @"{... the rest of the string ...}";
NSAutoreleasePool *aPool = [[NSAutoreleasePool alloc] init];
/*1*/ NSDictionary *dico = [resultsGeocodeLiteralString JSONValue]; // <-- Instruments still points here.
/*2a*/ self.resultsGeoCode = [[NSDictionary alloc] initWithDictionary:dico copyItems:YES];
/*2b*/ [self.resultsGeoCode release];
[aPool release];
所有NSString属性都具有“复制”属性。所有NSDictionary属性都具有retain属性。你可以看到我对任何字典项都做了深度复制
以下是dealoc方法:
- (void) dealloc {
/* NSString properties with copy attribute */
self.streetNumber = nil;
self.route = nil;
self.city = nil;
self.region = nil;
self.country = nil;
self.postalCode = nil;
self.previousStatusCode = nil;
self.region = nil;
/* I have tried it with and without these releases of the dictionary properties */
if (location_) [location_ release];
if (geometry_) [geometry_ release];
if (regionGeometries_) [regionGeometries_ release];
if (resultsGeoCode_) [resultsGeoCode_ release];
/* I would have thought these would be sufficient to release the retained properties */
// self.location = nil;
// self.geometry = nil;
// self.regionGeometries = nil;
// self.resultsGeoCode = nil;
[super dealloc];
}
Instruments说泄漏对象是一个NSCFString,负责的帧(我不知道是什么)是-[NSPlaceholderString initWithBytes:length:encoding:]
我希望这里没有太多的代码可供查看,但我还是难倒了。此外,我很好奇,是否有任何明显的误解,显示出如何属性设置行为。(所有的setter和getter都是合成的。)这不是100%的答案,因为我们不知道接下来会发生什么和之前会发生什么 我不确定,但有些事情你不必做:
首先: 而不是那三行。 如果不需要函数
resultsGeoCodeString
的参数,则可以释放它
第二:
self.geometry = [[NSDictionary alloc] initWithDictionary:geom copyItems:YES];
[self.geometry release];
为什么在分配完此对象后立即释放它?完成此对象后释放它。与上一点相同
在[pool release]之前代码>添加行<代码>[self.resultsGeoCode发布]
self.resultsGeoCode=nil代码>或更早
我建议您使用ARC而不是手动保留计数。一旦我理解了问题,我就可以将其抽象出来,我很乐意这样做。我想我已经很好地缩小了范围,我正在努力理解这里的一些原则。一旦我理解了它们,它们就会被分享。吉姆,你使用的是什么版本的SBJson?当前主设备(3.1alpha)正在使用ARC。这样可以防止任何泄漏。你能看看这个版本是否还有问题吗?嗨,斯蒂格。我使用的是3.0.1。我刚刚解决了这个问题,你会很高兴知道它不是SBJSON!我将修改我的问题以反映这一点,并说明问题所在。我尝试了NSJSONSerializer,同样的问题也出现了。工具仍然指向JSON序列化代码行。(我切换回SBJSON,因为我自定义了m对象的序列化。)感谢您的帮助。(1) 你能澄清你在第一条建议中的意思吗,“如果你不需要论证……”`resultsGeoCodingString“是一个NSString,我正在将它从JSON转换为NSDictionary。我的想法是返回的对象不是自动删除的,或者如果是自动删除的话,它会带走一些提取的对象。这就是为什么我转向复制字符串和深度复制字典的原因。(2)我的理解是,保留属性的setter将调用retain。因此此对象保留2X,因为我也使用init创建它。但这不应导致泄漏。如果您在分配结果GeocodingString之前的某个位置释放它,则应释放它。如果不释放,则保持原样。self.geometry=[[NSDictionary alloc]initWithDictionary:geom copyItems:YES]
根据我对内存管理的理解,这里您只保留了一次self.geometry
。我研究了您的建议,即问题可能源于参数resultsGeoCodingString
,但没有解决问题。我想我现在已经缩小了范围,这可能是SBJSON问题,我将修改我最初的任务Jim告诉我们,你是如何得到你的结果GeocodingString
。这可能会帮助我们给你正确的答案。
/*2a*/ self.resultsGeoCode = [[NSDictionary alloc] initWithDictionary:[resultsGeoCodeString JSONValue] copyItems:YES];
self.geometry = [[NSDictionary alloc] initWithDictionary:geom copyItems:YES];
[self.geometry release];