2011-08-09 6 views
0

私は客観的なcの初心者です。他のクラスからNSArrayを呼び出すと問題が発生します。 XMLフィードの解析とUItableviewの管理を行うクラスがあります。 NSURLConnectionを使用して非同期にすると、すべてのデータが解析されますが、配列が呼び出されると配列は空になるため、NSXMLParserメソッドを使用して同期的に処理が行われるため、奇妙です。 NSLogを呼び出すと、データが解析されているときにnewsStories配列に含まれるすべてのデータが表示されますが、呼び出すと何らかの形で削除されます。私が持っているパーサクラスとNSXMLParserのすべてのメソッドに別のクラス(xcode)から呼び出すと、NSArrayは空です

- (void)parseXMLFileAtUrl:(NSString *)URL { 
    data = [[NSMutableData alloc] init]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:URL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; 
    NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self]; 
    if (connection) { 
     data = [[NSMutableData alloc]init]; 
    } 
    [connection release]; 
} 
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    //Reset the data as this could be fired if a redirect or other response occurs 
    [data setLength:0]; 
} 
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)_data 
{ 
    //Append the received data each time this is called 
    [data appendData:_data]; 
} 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    //Start the XML parser with the delegate pointing at the current object 
    _parser = [[NSXMLParser alloc] initWithData:data]; 
    newsStories = [[NSMutableArray alloc] init]; 
    [_parser setDelegate:self]; 
    [_parser setShouldProcessNamespaces:NO]; 
    [_parser setShouldReportNamespacePrefixes:NO]; 
    [_parser setShouldResolveExternalEntities:NO]; 
    [_parser parse]; 
} 

そして、これは私は、配列を呼び出す方法です:

-(BOOL) loadData{ 
    NSString *latestUrl = [[NSString alloc] initWithString:feed]; 
    if ([latestArray count] == 0) { 
     news = [[news_parser alloc]init]; 
     [news parseXMLFileAtUrl:latestUrl]; 
     [self setArray:news.newsStories];--- here it says null for Array and for newsItems 
    } 
    [latestUrl release]; 
    return YES; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    array = [[NSMutableArray alloc]init]; 
    _News.rowHeight =85; 
    [self loadData]; 
    [self._News reloadData];  
} 

すべてのヘルプは、おかげでみんなをいただければ幸いです!よろしくです。 よろしくお願いします。 Appleのドキュメントから

答えて

2

...非同期の意味を理解していますか?これは、関数が返ってきて接続が続行され、コールバックが準備完了になったときにコールバックを行うことを意味します。これをコード化した方法では、接続を開始してすぐにデータを使用しようとします - それはまだありません!配列を使用する前に、connectionDidFinishLoadingの後まで待つ必要があります。

正確には非同期であることを意味するものについてさらに調査してください。あなたはそれを理解していないようです。

編集

あなたが私のポイントを逃しているように見えることから、私は明確にしましょう。あなたのviewDidLoad関数は、あなたのconnectionDidFinishLoadingコールバックが呼び出されるずっと前に終了します、そして、もちろんnewsStories配列はまだありません。 loadData関数で

[news parseXMLFileAtUrl:latestUrl]; 

を呼び出すと、接続が復帰するのを待たずに待機します。それが同期していれば、それはそうだが、非同期はそうではない。 (したがって、私は非同期が実際に何を意味しているかを調査するよう依頼します。その呼び出しが返されてからすぐに、ロードされたデータを使用しようとすると(connectionDidFinishLoadingが呼び出されるずっと前に)、あなたは自然にそこにデータを持っていません。

+0

こんにちは!私はconnectionDidFinishLoadingメソッドを実行しました: - (void)connectionDidFinishLoading:(NSURLConnection *)接続 { _parser = [[NSXMLParser alloc] initWithData:data]; newsItems = [[NSMutableArray alloc] init]; [_parser setDelegate:self]; [_parser setShouldProcessNamespaces:NO]; [_parser setShouldReportNamespacePrefixes:NO]; [_parser setShouldResolveExternalEntities:NO]; [_parser parse]; } 配列はデータを保持していますが、これを呼び出すときに、null.sorryが来たら、これはかなり基本的ですが、助けてくれてありがとうございます – marsalal1014

+0

今後はコメントにコードを貼り付けないでください。私は最初にあなたの記事を読んで、私はここでそれを繰り返す必要はありません。私の答えを読んで、実際に私が何を話しているのか分からない前に私の提案を試してください。 – taxilian

+0

こんにちはタクシー、そこにコードをコピーして申し訳ありません、私は自分自身を明確に説明していないと思った。私はあなたが赤字の後、私はいくつかの研究を行い、私はあなたが意味するものを得て、カップルのデバッグの後に私はそれを得ました。あなたの視点と説明に感謝します。申し訳ありませんが、私のコメントは無礼でした。ありがとう! – marsalal1014

0

可変オブジェクトは、一般的に、スレッドセーフではありません。スレッド可能なアプリケーションで可変オブジェクト を使用するには、アプリケーションでロックを使用して へのアクセスを同期させる必要があります。 (詳細は、「アトミック操作」を参照してください)。 一般的に、コレクションクラス(NSMutableArray、 NSMutableDictionaryなど)は、突然変異に関してはスレッドセーフではありません。 つまり、1つ以上のスレッドが同じ配列を変更している場合、問題 が発生することがあります。スレッドの安全性を保証するには、読み取りと書き込みが発生する箇所をロックする必要があります。

Reading thisが役に立ちます。それがあなたのアプリで何が起こっているのかは完全には分かりませんが、それは始めるのが良い場所のようです。

関連する問題