NSArray пуст, когда я вызываю его из другого класса (xcode) - PullRequest
0 голосов
/ 09 августа 2011

Я вроде новичка в target-c, и у меня возникают проблемы, когда я вызываю NSArray из другого класса. У меня есть класс, который обрабатывает разбор XML-фида и другой для управления UItableview. Это странно, потому что, когда это делается синхронно (с использованием методов NSXMLParser), все данные показываются в таблице, но когда я использую NSURLConnection, чтобы сделать его асинхронным, он анализирует все данные, но массив при вызове становится пустым. Если я вызываю NSLog, он показывает все данные, содержащиеся в массиве newsStories, когда данные анализируются, но каким-то образом удаляется, когда я его вызываю.

В классе анализатора у меня есть и все методы NSXMLParser:

- (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];    
}

Любая помощь будет оценена, спасибо, ребята! С уважением.

Ответы [ 2 ]

2 голосов
/ 09 августа 2011

... Вы понимаете, что значит асинхронный?Это означает, что ваша функция вернется, и соединение продолжится, сделав обратные вызовы, когда будет готово.Как вы это закодировали, вы запускаете соединение, а затем сразу же пытаетесь использовать данные - это еще не так!Вам нужно подождать, пока после connectionDidFinishLoading, прежде чем пытаться использовать массив.

Проведите еще несколько исследований о том, что именно означает быть асинхронным;кажется, вы этого не понимаете.

Редактировать

Позвольте мне уточнить, поскольку вы, похоже, не поняли мою точку зрения.Ваша функция viewDidLoad завершается задолго до того, как будет вызван обратный вызов connectionDidFinishLoading, и поэтому, конечно, массива newsStories еще нет.Когда вы вызываете:

[news parseXMLFileAtUrl:latestUrl];

в функции loadData, это не останавливает и не ожидает возврата соединения;если бы это было синхронно, то было бы, но асинхронно - нет.(Поэтому я прошу вас исследовать, что на самом деле означает асинхронность, чего, очевидно, вы еще не сделали).Поскольку этот вызов возвращается, а затем вы сразу же пытаетесь использовать загруженные данные (задолго до вызова connectionDidFinishLoading), у вас, естественно, нет никаких данных.

0 голосов
/ 09 августа 2011

Из документов Apple:

Изменяемые объекты, как правило, не являются поточно-ориентированными. Использовать изменяемые объекты в многопоточном приложении приложение должно синхронизировать доступ к их используя замки. (Для получения дополнительной информации см. «Атомные операции»). В Вообще, классы коллекции (например, NSMutableArray, NSMutableDictionary) не являются потокобезопасными, когда речь идет о мутациях. То есть, если один или несколько потоков изменяют один и тот же массив, проблемы может возникнуть. Вы должны заблокировать места, где происходит чтение и запись обеспечить безопасность резьбы.

Чтение этого может вам помочь. Не совсем уверен, что именно это происходит в вашем приложении, но похоже, что это хорошее место для начала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...