开发者

NSURL value being released unexpectedly

I have a very very strange problem and I am without a clue as to why its happening. Simply enough I have a class which stores an NSString and an NSURL. There can be many of these classes so I store them in a mutable array.

This array is used to populate a tableview. When a user hits a table cell I get one of the list class's from the array, get its URL property, and pass that to a detail view. This works fine 99% of the time but the other 1% of the time the URL property that I'm passing sometimes has become released.

Specifically in the debugger the NSURL says "invalid summary" and its urlstring property says ""

I've commented out every place that I release the NSURL. Oddly enough the NSString variable in the same class does not suffer from the same unwanted behavior.

// 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];
}

EDIT 1

I think I found the problem but I dont really understand whats going on.

In the listview showWithData method I was passing in a url and assigning it to a nsurl var of listview like this.

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

{
    if (  [super init]) {


        baseURL=data.URL;
}

baseURL was being released somehow (in the bowels of TBXML I think) and this was making the NSURL from the parent tableview class be released.

I changed the showWithData method to the following and the problem has ceased to occur. It seems that using 'copy' protected the original NSURL from being released. I dont understand it though because when I check in the debugger both the NSURl being passed to the method and the baseURL var both have the same memory address. Can somebody explain this ?

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

{
    if (  [super init]) {


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


Im surprised that this works at all

listData *rld = [listData alloc];

try this and your URL's may stop vanishing

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

also dont cap your ivars. It confuses the heck out of the synthesise directive sometimes.

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

}

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

@end


This might not help, at all, but it is something you could try. Instead of accessing the URL variable through rld.URL, try adding something like the following.

-(NSURL*)returnURLvalue {return URL;}

(with the appropriate declaration in the h file of course)

And use

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

to get at the variable value.

I emphasize that I don't know that this will work in your situation, but its often solved whatever inexplicable problem I was having with the . notation. Just a thought.


In case you're storing really a lot of elements in listDataArray, you might want to consider replacing the convenience constructor [NSURL URLWithString:...] by an explicit memory allocation with subsequent deallocation. Something along the lines of

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

The convenience constructor returns an auto-released object and the use of auto-released objects is discouraged in situations where many objects are created. See also the answer to this question.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜