0

JSON データを 2 秒ごとに取得し、それを別のクラスに渡して処理しようとしていますが、すべて正常に動作しますが、以下のコードには (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からのメモリリークログは以下です

    漏洩オブジェクト番号 アドレス サイズ 責任ライブラリ 責任フレーム
    __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 バイト Foundation -[NSPlaceholderString initWithBytes:length:encoding:]
4

1 に答える 1

0

まあ、それは単純に見えます。最初に、JSONDataを「assign」ではなく「retain」として定義し、その後の実行でTestMethodを呼び出すと、セッターを使用せず、インスタンス変数に直接アクセスするため、前のメソッドをリークします。他の場所ではJSONDataは必要ありませんが、このメソッドでは、ローカル変数として定義するだけで、特別なことは何もしません。自動リリースされます。そして2番目-同じことがtestArrayにも起こります。繰り返しますが、他の場所で必要ない場合は、ローカル変数として定義し、必要な場合は、セッターを使用します。

更新:今回はdeviceListArrayだけで、同様の問題が発生します。まず、次のように初期化します。

self.deviceListArray=[NSMutableArray array];

次に、割り当てるたびに、これを使用します。

self.deviceListArray = newObject;

Deallocで行う

[deviceListArrayリリース];

于 2011-05-08T23:27:14.030 に答える