Значение NSURL неожиданно высвобождается - PullRequest
1 голос
/ 23 марта 2011

У меня очень странная проблема, и я понятия не имею, почему это происходит. Достаточно просто у меня есть класс, который хранит NSString и NSURL. Таких классов может быть много, поэтому я храню их в непостоянном массиве.

Этот массив используется для заполнения таблицы. Когда пользователь попадает в ячейку таблицы, я получаю один из классов списка из массива, получаю его свойство URL и передаю его в подробный вид. Это хорошо работает в 99% случаев, но остальные 1% времени свойства URL, которые я передаю, иногда становятся свободными.

В частности, в отладчике NSURL говорит "недопустимая сводка", а его свойство urlstring говорит ""

Я прокомментировал каждое место, где я выпускаю NSURL. Как ни странно, переменная NSString в том же классе не страдает от того же нежелательного поведения.

// list data
@interface ListData : NSObject {
    NSURL *URL;
    NSString *Title;

}

@property(nonatomic,retain) NSURL *URL;
@property(nonatomic,copy) NSString *Title;

@end

#import "ListData.h"


@implementation ListData
@synthesize URL;
@synthesize Title;

-(void)dealloc
{
    [URL release];
    [Title release];


    [super dealloc];
}

@end

// table delegate method

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ListData *rld=nil;

    rld=[listDataArray objectAtIndex:indexPath.row];

    if (self.listView) {
        //[remixView closeRemix];

        [self.listView release];
        self.listView=nil;
    }

    // occassionaly the value of rld.URL is being released somehow
    self.listView = [[ListView alloc] showWithData:rld.URL ];


    self.listView.title = rld.remixTitle;

    [table.navigationController pushViewController:listView animated:YES];

}

//population of list array

listArray =[[NSMutableArray alloc]init];


while (listelement!=nil) {


    listData *rld = [listData alloc];

    [rld setURL:[NSURL URLWithString:[TBXML textForElement:[TBXML childElementNamed:@"url" parentElement:listelement]]]];
    [rld setTitle:[TBXML textForElement:[TBXML childElementNamed:@"title" parentElement:listelement]]];

    [listArray addObject:rld];

    [rld release];
    listelement = [TBXML nextSiblingNamed:@"list" searchFromElement:listelement];
}

РЕДАКТИРОВАТЬ 1

Я думаю, что нашел проблему, но я действительно не понимаю, что происходит.

В методе listview showWithData я передавал URL-адрес и присваивал его nsurl-переменной var listview следующим образом.

-(id) showWithData:(ListData *) data;

{
    if (  [super init]) {


        baseURL=data.URL;
}

baseURL каким-то образом выпускался (в недрах TBXML, я думаю), и это делало NSURL из родительского класса tableview.

Я изменил метод showWithData на следующий, и проблема перестала возникать. Похоже, что использование «copy» защитило исходный NSURL от выпуска. Я не понимаю этого, потому что, когда я проверяю в отладчике и NSURl, передаваемый методу, и baseURL var, оба имеют один и тот же адрес памяти. Может кто-нибудь объяснить это?

-(id) showWithData:(xListData *) data;

{
    if (  [super init]) {


        self.baseURL=[data.URL copy];
}

Ответы [ 3 ]

1 голос
/ 23 марта 2011

Я удивлен, что это работает вообще

listData *rld = [listData alloc];

попробуйте это, и ваши URL могут перестать исчезать

listData *rld = [[listData alloc] init];

также незакройте свои ивары.Это иногда сбивает с толку из директивы синтеза.

@interface ListData : NSObject {
    NSURL *url;
    NSString *title;

}

@property(nonatomic,retain) NSURL *url;
@property(nonatomic,copy) NSString *title;

@end
0 голосов
/ 23 марта 2011

В случае, если вы действительно храните много элементов в listDataArray, вы можете рассмотреть возможность замены вспомогательного конструктора [NSURL URLWithString: ...] на явное выделение памяти с последующим освобождением. Что-то вроде

NSURL* URL = [[NSURL alloc] initWithString:...];
rld.URL = URL;
[URL release];

Удобный конструктор возвращает автоматически выпущенный объект, и использование автоматически выпущенных объектов не рекомендуется в ситуациях, когда создается много объектов. Смотрите также ответ на этот вопрос .

0 голосов
/ 23 марта 2011

Это может вообще не помочь, но это то, что вы можете попробовать. Вместо доступа к переменной URL через rld.URL, попробуйте добавить что-то вроде следующего:

-(NSURL*)returnURLvalue {return URL;}

(с соответствующей декларацией в файле h, конечно)

И используйте

self.listView = [[ListView alloc] showWithData:[rld returnURLvalue]];

чтобы получить значение переменной.

Я подчеркиваю, что я не знаю, что это сработает в вашей ситуации, но это часто решает любую необъяснимую проблему, с которой я столкнулся. нотации. Просто мысль.

...