【问题标题】:Delegate property gets unset?委托属性未设置?
【发布时间】:2012-03-25 13:45:50
【问题描述】:

我遇到了一个不知道如何解决的问题。让我给出一些相关的代码。

FrontpageViewController (viewDidLoad)

NewsFetcher *newsFetcher = [[NewsFetcher alloc] initWithURL:url];
newsFetcher.delegate = self;
[newsFetcher loadData];

NewsFetcher.h

@property (nonatomic, unsafe_unretained) id <NewsFetcherDelegate> delegate;

我使用 unsafe_unretained 是因为我希望我的应用也能在 iOS 4 上运行,同时为了方便起见仍使用 ARC。

NewsFetcher.m

- (id)initWithURL:(NSURL *)url {

    self = [super init];

    if (self) {

        self.url = url;
        self.receivedData = [[NSData alloc] init];
    }

    return self;
}

- (void)loadData {

    NSLog(@"%@", self.delegate); // FrontpageViewController, as expected

    NSURLRequest *request = [NSURLRequest requestWithURL:self.url 
                                             cachePolicy:NSURLRequestReloadIgnoringCacheData 
                                         timeoutInterval:15];

    if (self.connectionInProgress)
        [self.connectionInProgress cancel];

    self.connectionInProgress = [[NSURLConnection alloc] initWithRequest:request
                                                                delegate:self
                                                        startImmediately:YES];
}

这一切都很好。 NewsFetcher 符合 NSURLConnectionDelegate 协议,所以下一个被调用的方法是connection:didReceiveData:。但是,当我在该方法中执行另一个 NSLog(@"%@", self.delegate) 时,我会得到不同的结果(EXEC_BAD_ACCESS、NSCFDictionary 等)。我认为这意味着我的 delegate 属性指向一个已释放的对象,这很奇怪,因为它应该是仍在屏幕上的视图控制器(因此不能被释放,对吧?)。

我的委托如何在一种方法中可用,但在下一种方法中不再可用?和unsafe_unretained有关系吗?

【问题讨论】:

    标签: objective-c ios


    【解决方案1】:

    调用者不会(按照惯例)保留委托对象。期望在您的对象上设置它的调用者将保留它。建议您将 Instruments 工具与僵尸(然后是泄漏)一起使用,看看发生了什么。

    【讨论】:

    • 好的,我已经这样做了,当我用 Zombies 运行 Instruments 时,它确实说我发送了一个消息,执行一个已释放对象。为什么我的 FrontpageViewController 在其视图仍在屏幕上时被释放?您说期望是设置它的调用者将保留它,但是由于它不会自动执行此操作,我自己该怎么做?我不认为让它成为一个强指针是这里想要的解决方案,是吗?
    • 不 - 不要让它成为一个强指针。您应该能够放大该实例并查看所有保留/释放以了解发生了什么。您是否显示任何模式或其他显示控制器?您还可以查看 didReceiveMemoryWarning - 如果资源不在屏幕上,默认实现将自动释放资源。
    • 目前没有其他视图控制器发挥作用。打开应用程序后,视图控制器会创建一个 NewsFetcher 实例,然后(从本地网络)下载并解析一个 RSS 文件。当它完成(可能需要一秒钟)解析时,委托对象(视图控制器)已经消失了。我对 Instruments 的经验很少,所以任何提示都会非常有帮助。那个视图控制器永远不会离开屏幕,所以我不认为它的内存不足(此外,我只是在模拟器上测试它)。
    • 花在学习 Instruments 上的时间一点都没有浪费我的朋友 - 对于 coles 的笔记,如果你可以花 45 分钟的时间来观看视频,强烈建议您查看 WWDC 视频,包括 2010 年和2011 (developer.apple.com/videos/wwdc/2011),像这些:developer.apple.com/videos/wwdc/2011/includes/…developer.apple.com/videos/wwdc/2010/?id=311。很好的演练如何准确地解决您所说的问题。
    • @bbum 在这里也有一个很好的链接,但这是针对保留周期而不是僵尸:friday.com/bbum/2010/10/17/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-08
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多