目标 c - YAJL 内存泄漏问题阵列



我正在尝试每 2 秒获取一次 JSON 数据并将其传递给另一个类进行处理,一切正常,但下面的代码似乎有内存泄漏(来自 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

仪器的内存泄漏日志如下

    泄露的对象 # 地址大小 负责库 负责框架    __NSArrayM,569 <多个> 17.78 KB MYTESTAPP3 -[YAJLDocument parserDidStartArray:]    Malloc 80 字节,480 <多个> 37.50 KB MYTESTAPP3 -[YAJLDocument parserDidStartArray:]    NSCFString,397  11.44 KB Foundation -[NSPlaceholderString initWithBytes:length:encoding:]    NSCFString, 0x4c1dac0 32 Bytes Foundation -[NSPlaceholderString initWithBytes:length:encoding:]

嗯,看起来很简单。首先,您将 JSONData 定义为"保留"而不是"分配",然后在后续运行中调用 TestMethod 时,您泄漏了前一个,因为您没有使用资源库,而是直接访问实例变量。如果你不需要在其他地方使用 JSONData,但这种方法,只需将其定义为局部变量,不要做任何特殊的事情 - 它是自动发布的。其次 - 同样的事情发生在testArray上。同样,如果你在其他地方不需要它,那么定义为局部变量,如果你这样做,那么使用setter。

更新:现在你有一个类似的问题,只是这次是deviceListArray。首先,像这样初始化它:

self.deviceListArray=[NSMutableArray array];

然后,每次要分配时,请使用以下命令:

self.deviceListArray = newObject;

在交易中做

[设备列表阵列发布];

最新更新