我试图每2秒获取一次JSON数据并将其传递给另一个类进行处理,一切正常但下面的代码似乎有内存泄漏(来自Instruments)但我无法弄清楚出了什么问题以及我怎么做修复,有人可以建议???
*更新了完整的逻辑,看起来传递给main方法的数组正在泄漏,而且Instruments错误地将其报告为YAJL泄漏...(不太确定你) *
@property (nonatomic,retain,readwrite) NSMutableArray *deviceListArray;
- (void)viewDidLoad
{
[super viewDidLoad];
deviceListArray=[[NSMutableArray alloc]init];
[self init];
TestClass *initiateData = [GetData alloc]init];
[initiateData startTimer];
[initiateData release];
}
- (id) init{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(receiveDeviceListNotification:)
name:@"devicelist"
object:nil];
}
- (void) receiveDeviceListNotification:(NSNotification *) notification{
deviceListArray=[notification object];
[deviceListTable reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [deviceListArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
[deviceListArray retain]; //CRASHES WITHOUT RETAIN specified here
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.textLabel.textColor = [UIColor redColor];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
[cell.textLabel setText:[deviceListArray objectAtIndex:indexPath.row]]; //CRASHES if i remove the retain on devicelistarray
return cell;
}
@class TestClass;
@implementation TestClass
- (void)startTimer:(NSString *)timerstring
{
if(timerstring ==@"StartNow")
{
NSLog(@"Timer started");
[NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(TestMethod:) userInfo:nil repeats:YES];
}
else{
NSLog(@"string not received");
}
}
-(void)TestMethod:(NSTimer *)Timer {
NSTimeInterval timeNow= [NSDate timeIntervalSinceReferenceDate];
NSData *JSONData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.example/data.json"]];
NSArray *testArray=[JSONData yajl_JSON]; //MEMORY LEAK HERE
if(testArray==nil)
{
NSLog(@"Array is nil");
}
else
{
NSArray *arrayNumberOne=[[testArray valueForKey:@"devicelist"]objectAtIndex:0];
NSArray *arrayNumberTwo=[testArray valueForKey:@"arrayNumberTwo"];
NSArray *arrayNumberThree=[testArray valueForKey:@"arrayNumberThree"];
float dowloadY=[[arrayNumberTwo objectAtIndex:0]floatValue];
float uploadY=[[arrayNumberThree objectAtIndex:0]floatValue];
NSDictionary *newarrayNumberTwoData= [NSDictionary dictionaryWithObjectsAndKeys:
[NSDecimalNumber numberWithInt:timeNow], [NSNumber numberWithInt:0],
[NSDecimalNumber numberWithFloat:dowloadY], [NSNumber numberWithInt:1],nil
] ;
NSDictionary *newarrayNumberThreeData= [NSDictionary dictionaryWithObjectsAndKeys:
[NSDecimalNumber numberWithInt:timeNow], [NSNumber numberWithInt:0],
[NSDecimalNumber numberWithFloat:uploadY], [NSNumber numberWithInt:1],nil
] ;
[[NSNotificationCenter defaultCenter] postNotificationName:@"devicelist" object:arrayNumberOne];
[[NSNotificationCenter defaultCenter] postNotificationName:@"TestData2" object:newarrayNumberTwoData];
[[NSNotificationCenter defaultCenter] postNotificationName:@"TestData3" object:newarrayNumberThreeData];
}
}
-(void) dealloc{
[super dealloc];
}
@end
来自Instruments的内存泄漏日志
Leaked Object # Address Size Responsible Library Responsible Frame __NSArrayM,569 < multiple > 17.78 KB MYTESTAPP3 -[YAJLDocument parserDidStartArray:] Malloc 80 Bytes,480 < multiple > 37.50 KB MYTESTAPP3 -[YAJLDocument parserDidStartArray:] NSCFString,397 < multiple > 11.44 KB Foundation -[NSPlaceholderString initWithBytes:length:encoding:] NSCFString, 0x4c1dac0 32 Bytes Foundation -[NSPlaceholderString initWithBytes:length:encoding:]
答案 0 :(得分:0)
嗯,看起来很简单。 首先,您将JSONData定义为“retain”而不是“assign”,然后在后续运行中调用TestMethod时,泄漏前一个,因为您没有使用setter,而是直接访问实例变量。 如果你不需要任何其他地方的JSONData,但是这个方法,只需将它定义为局部变量,并且不做任何特殊的事情 - 它是自动释放的。第二 - 同样的事情发生在testArray上。同样,如果你在其他地方不需要它,那么定义为局部变量,如果你这样做,那么使用setter。
更新: 现在你有一个类似的问题,这次只是使用deviceListArray。 首先,将其初始化为:
self.deviceListArray=[NSMutableArray array];
然后,每次要分配时,请使用:
self.deviceListArray = newObject;
在dealloc做
[deviceListArray release];