освободена памет в tableview: съобщение, изпратено до освободен екземпляр

Опитах се да потърся други проблеми, но не можах да намеря нищо, което да съответства, така че ето го:

Опитвам се да покажа текст в табличния изглед, така че използвам този код:

// StockData is an object I created and it pulls information from Yahoo APIs based on 
//  a stock ticker stored in NSString *heading

    NSArray* tickerValues = [heading componentsSeparatedByString:@" "];
StockData *chosenStock = [[StockData alloc] initWithContents:[tickerValues objectAtIndex:0]];
[chosenStock getData];

// Set up the cell...
NSDictionary *tempDict = [chosenStock values];
NSArray *tempArr = [tempDict allValues];
cell.textLabel.text = [tempArr objectAtIndex:indexPath.row];
return cell;

Всичко това е под cellForRowAtIndexPath

Когато се опитам да освободя обекта selectedStock, все пак получавам тази грешка: [CFDictionary release]: съобщение, изпратено до освободен екземпляр 0x434d3d0

Опитах да използвам NSZombieEnabled и Build and Analyze за откриване на проблеми, но засега без успех. Дори стигнах толкова далеч, че коментирах части от кода с NSLog, но без успех. Ще публикувам кода за StockData под това. Доколкото мога да разбера, нещо се освобождава, преди да направя изданието, но не съм сигурен как. Единственото място, където имам освобождаване в моя код, е под извикването на метода dealloc.

Ето кода на StockData:

// StockData contains all stock information pulled in through Yahoo! to be displayed

@implementation StockData

@synthesize ticker, values;

- (id) initWithContents: (NSString *)newName {
    if(self = [super init]){
        ticker = newName;
    }
    return self;
}

- (void) getData {

    NSURL *url = [NSURL URLWithString: [NSString stringWithFormat:@"http://download.finance.yahoo.com/d/quotes.csv?s=%@&f=%@&e=.csv", ticker, @"chgvj1"]];
    NSError *error;
    NSURLResponse *response;
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    NSData *stockData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

    if(stockData) {
        NSString *tempStr = [[NSString alloc] initWithData:stockData encoding:NSASCIIStringEncoding];       

        NSArray *receivedValuesArr = [tempStr componentsSeparatedByString:@","];
        [tempStr release];

        values = [NSDictionary dictionaryWithObjects:receivedValuesArr forKeys:[@"change, high, low, volume, market" componentsSeparatedByString:@", "]];
    } else {
        NSLog(@"Connection failed: %@", error);
    }
}

- (void)dealloc {
    [ticker release];
    [values release];   
    [super dealloc];

    NSLog(@"Release took place fine");
}

@end

person Kirn    schedule 26.05.2010    source източник


Отговори (1)


Е, виждам потенциален проблем...в този фрагмент

   (id) initWithContents: (NSString *)newName{

  if(self = [super init]){

  ticker = newName; 
  } return self;

Вие не запазвате тикер, u syntheisze ticker, но трябва да го присвоите, като кажете self.ticker=newName или ticket=[newName retain], така че тук не запазвате тикер и в dealloc освобождавате тикер...така че вие прекомерно освобождават тикер, което ще причини проблема ви... Също така, когато освободите този масив, който съдържа стойността на низа на вашия тикер, ако се опитате да получите достъп до свойствата на тикер на обекта, той ще се срине, тъй като не сте го запазили.

person Daniel    schedule 26.05.2010
comment
Добър улов, но бих препоръчал да не използвате self.ticker = newName във вашия init метод. По-безопасно е да използвате ticker = [newName copy]. Тази практика се препоръчва в случай, че всеки път променяте инструмента за достъп на свойството за ticker в нещо по-сложно. След секунда ще намеря връзка към пълния аргумент. - person e.James; 26.05.2010
comment
Хей благодаря за бързия отговор! Това проработи!! Имам обаче един въпрос. В свойството за ticker го зададох на (nonatomic, retain). Мислех, че това би свършило работа за стойността, която получи от newName. Искате да кажете, че трябваше да запазя обекта newName, към който сочи тикерът? Задаването на свойството за тикер за запазване не прави това? - person Kirn; 26.05.2010
comment
Надникнете в отговора ми на друг въпрос за повече подробности: stackoverflow.com/questions/1394360/ - person e.James; 26.05.2010
comment
Ето връзката, която обещах: stackoverflow.com/questions/192721/ - person e.James; 26.05.2010
comment
когато декларирате свойство и го синтезирате, трябва да получите достъп до генерирания сетер, като кажете self.propertyname, за да може да се запази... да, e.james, по-добре е да използвате синтезираното свойство, просто показвах алтернативи. - person Daniel; 26.05.2010
comment
@Kirn: Радвам се да помогна! Само кратка бележка относно етикета на сайта: тъй като Даниел ви е предоставил правилния отговор, обичайно е да гласувате за отговора му, както и да го отбелязвате като приет. Това в никакъв случай не е задължително, но това е начинът, по който обикновено се правят нещата. Забавлявайте се с кодирането! :) - person e.James; 26.05.2010
comment
Продължавам да се опитвам да гласувам за, но мисля, че имам нужда от определена репутация (точки?), за да го направя. Благодаря много момчета. - person Kirn; 01.06.2010