2012-03-08 96 views
0

我遇到了一個我不確定如何解決的問題。讓我給出一些相關的代碼。委託屬性被取消設置?

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有關?

回答

1

調用者不保留委託對象(按慣例)。期望的是,設置在你的對象上的調用者將保留它。建議您使用帶有殭屍的儀器工具(然後使用泄漏)來查看發生了什麼。

+0

好吧,我已經完成了這個,當我運行有殭屍的儀器時,它確實表示我發送了一個消息來執行一個釋放對象。我的FrontpageViewController如何在其視圖仍然在屏幕上時發佈?你說期望的是設置它的調用者會保留它,但因爲它不會自動執行此操作,所以我怎樣才能自己做到這一點?我不認爲使它成爲一個強有力的指針就是期望的解決方案,是嗎? – 2012-03-08 01:25:22

+0

不 - 不要讓它成爲一個強大的指針。您應該能夠放大該實例並查看所有保留/版本以查看正在發生的事情。你是否顯示任何模態或其他顯示控制器?你也可以看看didReceiveMemoryWarning - 默認的實現會自動釋放資源,如果他們不在屏幕上。 – 2012-03-08 12:44:36

+0

目前沒有其他視圖控制器可以使用。在打開應用程序後,視圖控制器將創建NewsFetcher的一個實例,然後下載(從本地網絡)並解析RSS文件。當它完成(可能需要第二次)解析時,委託對象(視圖控制器)已經消失。我對樂器的使用經驗很少,所以任何提示都會非常有幫助。該視圖控制器永遠不會離開屏幕,所以我不認爲它的內存不足(另外,我只在模擬器上測試它)。 – 2012-03-08 20:11:09