【问题标题】:iOS - Why my NSURL isn't retained in the init method?iOS - 为什么我的 NSURL 没有保留在 init 方法中?
【发布时间】:2012-02-23 06:00:30
【问题描述】:

我正在创建一个具有 2 个属性的新 UIViewController:

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

并合成:

@synthesize url = _url;
@synthesize title = _title;

在我的自定义初始化方法中,我没有像内存管理指南所说的那样使用 setter,但是当我需要使用 viewDidLoad 中的属性时,url 似乎是空的,标题没有

- (id)initWithURL:(NSURL *)url andTitle:(NSString *)titleTemp
{
    self = [super initWithNibName:@"navigatorViewController" bundle:nil];
    if (self) {
        _url = url;
        _title = titleTemp;
    }
    return self;
}

- (void)viewDidLoad
{
     [super viewDidLoad];
     // Do any additional setup after loading the view from its nib.
     [_titreBarButtonItem setTitle:_title];

     NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:_url];
    [_webView loadRequest:urlRequest];
    [urlRequest release];
}

我可以看到我的标题,但我的网页视图是空白的。 如果我在 init 中使用 self.url,它就可以工作!

你有什么想法吗?

PS:这是我如何调用我的 init :

NSString *urlString = [[[NSBundle mainBundle] pathForResource:@"infos" ofType:@"html"] copy];
NSURL *url = [[NSURL alloc] initFileURLWithPath:urlString];
[urlString release];
navigatorViewController *navigatorVC = [[navigatorViewController alloc] initWithURL:url andTitle:@"Infos"];
[url release];
[self presentViewController:navigatorVC animated:YES completion:nil];
[navigatorVC release];

非常感谢

【问题讨论】:

  • 如果您使用的是@synthesize,请阅读this,了解“在后台”发生的情况。还要确保你了解objective-c中的内存管理retainrelease等。

标签: iphone objective-c ios memory-management nsurl


【解决方案1】:

您必须使用以下任一方式保留 URL:

self.url = url;

在init方法中或在init方法中分配url后调用retain。

_url = url;
[_url retain];

【讨论】:

  • 并且在你调用retain之后不要忘记在dealloc中的self.url上调用release。
【解决方案2】:

您将属性设置为保留,但这仅适用于您使用合成的 getter。通过直接在 ivar 上设置值,您绕过了这一点并且该值不会被保留

你应该这样做(当你已经有 setter 时可能不是一个好方法):

_url = [url retain];

或更好:

self.url = url;

或者正如 matt 在 cmets 中所说的更好:使用 ARC

【讨论】:

  • 除此之外,这是 ARC 工作的乐趣所在,因为它会在您执行 _url = url 时为您添加保留。因此,如果您愿意,您可以绕过您的设置器并获得适当的内存管理的好处。
  • 好点@mattjgalloway,所以这里的答案真的是:保留自己,使用setter,或者使用ARC
【解决方案3】:

如果你编写了一个自定义的init 方法,你需要做的是保留你自己:

- (id)initWithURL:(NSURL *)url andTitle:(NSString *)titleTemp
{
    self = [super initWithNibName:@"navigatorViewController" bundle:nil];
    if (self) {
        _url = [url retain];
        _title = [titleTemp retain];
    }
    return self;
}

它与标题一起工作只是变量可能稍后发布,然后NSURL 传入 init 方法。

【讨论】:

    【解决方案4】:

    您需要使用copyretain 添加参考(对于您持有的):

    _url = [url copy];
    _title = [titleTemp copy];
    

    _url = [url retain];
    _title = [titleTemp retain];
    

    【讨论】:

    • @Dave 标题是 NSString 文字 - 它是不朽的
    猜你喜欢
    • 1970-01-01
    • 2017-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    • 2021-07-26
    • 2011-11-16
    • 1970-01-01
    相关资源
    最近更新 更多