【问题标题】:NSURL value being released unexpectedlyNSURL 值被意外释放
【发布时间】:2011-07-21 10:28:11
【问题描述】:

我有一个非常奇怪的问题,我不知道它为什么会发生。 很简单,我有一个存储 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 并将其分配给 listview 的 nsurl var,如下所示。

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

{
    if (  [super init]) {


        baseURL=data.URL;
}

baseURL 以某种方式被释放(我认为是在 TBXML 的内部),这使得父 tableview 类中的 NSURL 被释放。

我将 showWithData 方法更改为以下,问题已停止出现。似乎使用“复制”保护了原始 NSURL 不被释放。不过我不明白,因为当我签入调试器时,传递给方法的 NSURl 和 baseURL var 都具有相同的内存地址。有人可以解释一下吗?

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

{
    if (  [super init]) {


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

【问题讨论】:

  • 如何初始化listDataArray?
  • 你的意思是对象被释放了吗?您是否遇到错误的访问崩溃?指针是否突然指向空?还是指向一个包含空值的有效对象?
  • 具有空值的有效对象。
  • @hennes。 listDataArray =[[NSMutableArray alloc]init];
  • @dubbeat 不,我的意思是你如何用数据填充数组? (抱歉没有具体说明。)

标签: iphone objective-c memory-management nsurl


【解决方案1】:

我很惊讶这完全有效

listData *rld = [listData alloc];

试试这个,你的网址可能会停止消失

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

也不要限制你的 ivars。它有时会混淆综合指令。

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

}

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

@end

【讨论】:

  • "self.listView = [[ListView alloc] showWithData:rld.URL ];"出于类似的原因,看起来很可疑。如果 showWithData: 是一个初始化器,它应该被命名为 initWithData:.
【解决方案2】:

这可能一点用都没有,但您可以尝试一下。不要通过 rld.URL 访问 URL 变量,而是尝试添加如下内容。

-(NSURL*)returnURLvalue {return URL;}

(当然,在 h 文件中有适当的声明)

并使用

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

获取变量值。

我强调,我不知道这是否适用于您的情况,但它通常可以解决我遇到的任何莫名其妙的问题。符号。只是一个想法。

【讨论】:

  • 您能解释一下为什么这与使用 rld.URL 相比会有什么不同吗?
  • 不应该,但我发现有时会。我从来没有找到一个很好的答案来解释为什么。不知道会不会影响这个问题,但它为我解决了类似的问题。
【解决方案3】:

如果您在 listDataArray 中存储了非常多的元素,您可能需要考虑通过显式内存分配和随后的释放来替换便利构造函数 [NSURL URLWithString:...]。类似于

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

便捷构造函数返回一个自动释放的对象,并且在创建许多对象的情况下不鼓励使用自动释放的对象。另请参阅this question 的答案。

【讨论】:

  • 你能假设为什么我的 NSURL 大部分时间都很好,只是偶尔它是空的?
  • @dubbeat 我怀疑它与自动发布有关,并且 URL 仅被保留(而标题被复制)。在某些时候,自动释放池会溢出,然后必须释放一些东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-02
  • 1970-01-01
  • 1970-01-01
  • 2013-05-24
  • 2012-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多