нераспознанный селектор отправляется экземпляру при создании NSDictionary с твитами

Я ищу в Твиттере твиты с этим кодом:

- (void)fetchTweets
{

NSURL *url = [NSURL URLWithString:@"http://search.twitter.com/search.json"];
NSDictionary *params = [NSDictionary dictionaryWithObject:@"#winning" forKey:@"q"];

TWRequest *request = [[TWRequest alloc] initWithURL:url 
                                         parameters:params 
                                      requestMethod:TWRequestMethodGET];

[request performRequestWithHandler:
 ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {

     if (responseData) {
         NSError *jsonError;
         tweets = 
         [NSJSONSerialization JSONObjectWithData:responseData 
                                         options:kNilOptions
                                           error:&jsonError];


         if (tweets) {
            // NSLog(@"%@", tweets);
         } 

         else { 
             NSLog(@"%@", jsonError);
         }

     }

     [[self delegate] receivedTweets];

 }];

[self performSelector:@selector(fetchTweets) withObject:nil afterDelay:30];

Переменная tweets представляет собой NSArray, и я пытаюсь поместить ее в NSDictionary с помощью этого кода:

NSDictionary *tweet = [[TwitterHandler sharedInstance].tweets objectAtIndex:indexPath.row];

Я определенно получаю текст JSON для твитов, но при попытке добавить их в словарь, чтобы я мог в конечном итоге поместить их в таблицу, я получаю ошибку «неопознанный селектор, отправленный в экземпляр».

Я не уверен, почему я получаю это, и любая помощь будет оценена по достоинству.


person Mike Richards    schedule 25.05.2012    source источник
comment
Можете ли вы добавить фактическое сообщение об ошибке? Он должен иметь имя селектора и тип экземпляра.   -  person Phillip Mills    schedule 25.05.2012
comment
@PhillipMills *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0xdec1140'   -  person Mike Richards    schedule 25.05.2012
comment
Либо ваш массив твитов освобождается, а память повторно используется для хранения словаря, либо, возможно, JSONObjectWithData возвращается словарь. Когда вы раскомментировали // NSLog(@"%@", tweets);, что он сказал?   -  person Phillip Mills    schedule 25.05.2012
comment
Журнал дал мне твиты в формате JSON, которые я искал.   -  person Mike Richards    schedule 25.05.2012
comment
Но показал ли он их как массив или словарь???   -  person Phillip Mills    schedule 25.05.2012
comment
Он показывает их как словарь   -  person Mike Richards    schedule 25.05.2012
comment
Хорошо... тогда проблема в том, что словарь действительно не знает, как получить objectAtIndex:.   -  person Phillip Mills    schedule 25.05.2012
comment
Я думаю, я смущен тем, как твиты отображаются как словарь, когда я объявил его как массив   -  person Mike Richards    schedule 25.05.2012
comment
Редактирование J_D ниже! То, как вы его объявляете, не меняет его внутреннего содержания и методов, которые оно понимает.   -  person Phillip Mills    schedule 25.05.2012


Ответы (3)


В этом коде:

 if (responseData) {
         NSError *jsonError;
         tweets = 
         [NSJSONSerialization JSONObjectWithData:responseData 
                                         options:kNilOptions
                                           error:&jsonError];


         if (tweets) {
            // NSLog(@"%@", tweets);
         } 

         else { 
             NSLog(@"%@", jsonError);
         }

Является ли tweets тем же, что вы получаете с этим кодом:

[[TwitterHandler sharedInstance].tweets

Если это так, мне кажется, что вы назначаете его объекту с автоматическим освобождением, поэтому в конечном итоге он будет выпущен, и вы получите указатель на выпущенный объект.

Лучше сохраните его или используйте свойство сохранения при его назначении.

Что-то типа

tweets = 
         [[NSJSONSerialization JSONObjectWithData:responseData 
                                         options:kNilOptions
                                           error:&jsonError] retain];

или, предполагая, что tweets является удерживаемым свойством:

self.tweets = 
         [NSJSONSerialization JSONObjectWithData:responseData 
                                         options:kNilOptions
                                           error:&jsonError];

Не забудьте выпустить его, когда он больше не понадобится (по крайней мере, в dealloc вашего класса)

ИЗМЕНИТЬ

Хорошо, вот в чем дело, и это не имеет ничего общего с управлением памятью (неправильная первоначальная догадка!): Я попробовал ваш URL, и он возвращает:

{"error":"You must enter a query."}

Это словарь JSon. Затем синтаксический анализатор JSON идентифицирует это как словарь и возвращает вам словарь. Вы можете сохранить его в NSArray*, но создаваемый объект по-прежнему является словарем и будет реагировать только на методы NSDictionary. Как видно из вашего комментария, когда вы его печатаете, он печатает словарь.

person J_D    schedule 25.05.2012
comment
Я использую ARC, поэтому я не могу использовать свойство сохранения. Я пробовал self.tweets, но все равно получаю то же сообщение об ошибке. - person Mike Richards; 25.05.2012
comment
Я не очень хорошо знаком с ARC, кроме того, что в основном знаю, что он делает, но есть ли способ различать свойства, которые назначают или сохраняют объекты? Потому что для работы self.tweets свойство tweets должно быть объявлено как свойство сохранения с кодом, подобным (в не-ARC): @property (nonatomic, keep) NSDictionary * tweets; - person J_D; 25.05.2012
comment
У меня он объявлен как @property (strong, nonatomic) NSArray *tweets; - person Mike Richards; 25.05.2012
comment
Я добавил правку, объясняющую, почему вы получаете словарь, который не отвечает на вызов NSArray, который вы пытаетесь использовать. - person J_D; 25.05.2012
comment
Очень полезно знать. Я попробую добавить в свою таблицу метод NSDictionary. - person Mike Richards; 25.05.2012
comment
Вы должны проверить, какой формат JSON вы получаете. Я не знаю API твиттера, но для успешных запросов он вроде бы складывает все твиты в массив, этот массив находится под ключевыми результатами большого словаря, который вы получаете в качестве ответа (на основе примера, который я нашел в гугле). - person J_D; 25.05.2012

У меня было это однажды, и это было приложение, выпускающее контроллер представления, проверьте, выпускается ли ваш контроллер представления.

person virindh    schedule 25.05.2012
comment
Я уверен, что его не выпускают - person Mike Richards; 25.05.2012
comment
выполняйте код, который вызывает ошибку, только если objectatindex равен != nil, чтобы не было ошибки - person virindh; 25.05.2012
comment
Это не поможет, так как сбой вызывает вызов objectAtIndex. Кроме того, в Objective-C нет ничего плохого в вызове метода для нулевого объекта. Он просто ничего не сделает и вернет nil/0, если ему нужно что-то вернуть. - person J_D; 25.05.2012

[NSJSONSerialization JSONObjectWithData:responseData 
                                options:kNilOptions
                                  error:&jsonError];

Это возвращает объект NSDictionary твитов. Результаты поиска в Твиттере с этого URL-адреса можно отфильтровать, выполнив поиск содержимого в ключе results.

АКА:

NSDictionary *jsonTweet = [NSJSONSerialization JSONObjectWithData:responseData 
                                                          options:kNilOptions
                                                          error:&jsonError];

NSArray *tweet = [jsonTweet objectForKey:@"results"];

Затем твиты можно повторять, поскольку они находятся в NSArray.

person Mike Richards    schedule 13.06.2012