2014-12-09 4 views
0

Я искал ответы для этого, но до сих пор не смог решить, как исправить проблему. Этот -[NSNull length]: unrecognized selector sent to instance и этот [NSNull length]: unrecognized selector sent to instance 0x43fe068 не помогли.iOS 8 работает, но iOS 7 сбой - [NSNull length]: непризнанный селектор отправлен в экземпляр

Я работаю над чат-приложением с фреймворком Parse, и у меня возникла проблема с меткой времени, когда сообщение чата вышло из строя, поэтому я удалил строки, которые были не в порядке, из моей базы данных Parse, используя Databrowser. Когда я протестировал приложение, это, похоже, устранило проблему на моем iPhone 6 Plus и на симуляторе iPhone 6, работающем под управлением iOS 8. Однако при открытии той же комнаты для чатов на моем iPhone 5 под управлением iOS 7 приложение последовательно срабатывает следующая ошибка.

-[NSNull length]: unrecognized selector sent to instance

Я понятия не имею, почему не удаление строки может вызвать, чтобы это произошло, и почему только прошивкой 7? Я установил точку останова всех исключений, и вот оскорбительная строка вместе с скриншотом.

self.lastMessageLabel.textColor = [UIColor redColor]; 

enter image description here

я все еще получаю NSNull length аварии, даже когда я закомментировать эту строку, но он ломает в общей main.m.

Любые предложения о том, как решить эту проблему, будут оценены. Благодарю.

EDIT 1: Вот код моего ChatView.m, который загружается моим PrivateInbox.

- (void)loadMessages { 

    if (isLoading == NO) 
    { 
     isLoading = YES; 
     JSQMessage *message_last = [messages lastObject]; 

     PFQuery *query = [PFQuery queryWithClassName:PF_CHAT_CLASS_NAME]; 
     [query whereKey:PF_CHAT_ROOM equalTo:chatroomId]; 

     if (message_last != nil) { 
      [query whereKey:PF_CHAT_SENTDATE greaterThan:[self.dateFormatter stringFromDate:message_last.date]]; 
     } 

     [query includeKey:PF_CHAT_USER]; 
     [query orderByAscending:PF_CHAT_SENTDATE]; 
     [query addAscendingOrder:PF_CHAT_CREATEDAT]; 
     [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) 
     { 
      if (error == nil) 
      { 
       for (PFObject *object in objects) 
       { 
        PFUser *user = object[PF_CHAT_USER]; 
        [users addObject:user]; 

        if(![object[PF_CHAT_TEXT] isKindOfClass:[NSNull class]]) { 

         NSDate* sentDate; 
         if(object[PF_CHAT_SENTDATE] != nil) 
          sentDate = [self.dateFormatter dateFromString:object[PF_CHAT_SENTDATE]]; 
         else 
          sentDate = object.createdAt; 

         JSQTextMessage *message = [[JSQTextMessage alloc] initWithSenderId:user.objectId senderDisplayName:user.objectId date:sentDate text:object[PF_CHAT_TEXT]]; 
         [messages addObject:message]; 

        } else if(object[PF_CHAT_PHOTO] != nil) { 

         NSDate* sentDate; 
         if(object[PF_CHAT_SENTDATE] != nil) 
          sentDate = [self.dateFormatter dateFromString:object[PF_CHAT_SENTDATE]]; 
         else 
          sentDate = object.createdAt; 

         PFFile* photoFile = object[PF_CHAT_PHOTO]; 
         JSQPhotoMediaItem *photoItem = [[JSQPhotoMediaItem alloc] init]; 
         JSQMediaMessage *photoMessage = [[JSQMediaMessage alloc] initWithSenderId:user.objectId 
                       senderDisplayName:user.objectId 
                          date:sentDate 
                          media:photoItem]; 
         [messages addObject:photoMessage]; 

         { 
          [photoFile getDataInBackgroundWithBlock:^(NSData *data, NSError *error) { 
           photoItem.image = [UIImage imageWithData:data]; 
           [self.collectionView reloadItemsAtIndexPaths:[NSArray arrayWithObjects:[NSIndexPath indexPathForItem:[messages indexOfObject:photoMessage] inSection:0], nil]]; 
          }]; 
         } 

        } else if(object[PF_CHAT_VIDEO] != nil) { 

         NSDate* sentDate; 
         if(object[PF_CHAT_SENTDATE] != nil) 
          sentDate = [self.dateFormatter dateFromString:object[PF_CHAT_SENTDATE]]; 
         else 
          sentDate = object.createdAt; 

         PFFile* videoFile = object[PF_CHAT_VIDEO]; 
         JSQVideoMediaitem *videoItem = [[JSQVideoMediaitem alloc] initWithFileURL:[NSURL URLWithString:[videoFile url]] isReadyToPlay:YES]; 
         JSQMediaMessage *videoMessage = [[JSQMediaMessage alloc] initWithSenderId:user.objectId 
                       senderDisplayName:user.objectId 
                        date:sentDate 
                         media:videoItem]; 
         [messages addObject:videoMessage]; 
        } 
       } 

       if ([objects count] != 0) { 
        [JSQSystemSoundPlayer jsq_playMessageReceivedSound];      
        [self resetUnreadCount]; 
        [self finishReceivingMessage]; 
       } 
      } 
      else [ProgressHUD showError:@"Network error."]; 
      isLoading = NO; 
     }]; 
    } 
} 

EDIT 2: Я попытался NSNullSafe от Ник Локвуд https://github.com/nicklockwood/NullSafe, что позволило Частной Входящие открыть без сбоев и получает меня мимо ошибки Длина NSNull, но я думаю, что как раз маскирует проблему, и я до сих пор не» я знаю, почему он не сбой на iOS 8, но произошел сбой на iOS 7.

ответ

1

Я не думаю, что это может быть связано с различиями между двумя оперативными системами.
Крушение довольно ясно, вы отправляете сообщение объекту класса NSNUll, который не может его обработать.
Тот факт, что вы используете синтаксический анализ или веб-службы в целом, заставляет меня думать, что этот объект был создан задним концом как null в JSON и преобразован в объект NSNull с помощью анализа JSON.
Вы должны найти способ обработки объекта NSNull, вероятно, на уровне анализа.

+0

Я только что обновил сообщение с помощью дополнительного кода, чтобы вы могли видеть часть NSNull вызываемого кода. –

0

@Andrea правильно, если вы не можете понять это из вашего API (сервер) стороны, то, вот категории NSDictionaryNSArray и который удаляет любые NSNull объекта и ваше приложение не будет врезаться.

@interface NSDictionary (NullReplacement) 

- (NSDictionary *)dictionaryByReplacingNullsWithBlanks; 

@end 

@interface NSArray (NullReplacement) 

- (NSArray *)arrayByReplacingNullsWithBlanks; 

@end 

@implementation NSDictionary (NullReplacement) 

- (NSDictionary *)dictionaryByReplacingNullsWithBlanks { 
    const NSMutableDictionary *replaced = [self mutableCopy]; 
    const id nul = [NSNull null]; 
    const NSString *blank = @""; 

    for (NSString *key in self) { 
     id object = [self objectForKey:key]; 
     if (object == nul) [replaced setObject:blank forKey:key]; 
     else if ([object isKindOfClass:[NSDictionary class]]) [replaced setObject:[object dictionaryByReplacingNullsWithBlanks] forKey:key]; 
     else if ([object isKindOfClass:[NSArray class]]) [replaced setObject:[object arrayByReplacingNullsWithBlanks] forKey:key]; 
    } 
    return [NSMutableDictionary dictionaryWithDictionary:[replaced copy]]; 
} 

@end 

@implementation NSArray (NullReplacement) 

- (NSArray *)arrayByReplacingNullsWithBlanks { 
    NSMutableArray *replaced = [self mutableCopy]; 
    const id nul = [NSNull null]; 
    const NSString *blank = @""; 
    for (int idx = 0; idx < [replaced count]; idx++) { 
     id object = [replaced objectAtIndex:idx]; 
     if (object == nul) [replaced replaceObjectAtIndex:idx withObject:blank]; 
     else if ([object isKindOfClass:[NSDictionary class]]) [replaced replaceObjectAtIndex:idx withObject:[object dictionaryByReplacingNullsWithBlanks]]; 
     else if ([object isKindOfClass:[NSArray class]]) [replaced replaceObjectAtIndex:idx withObject:[object arrayByReplacingNullsWithBlanks]]; 
    } 
    return [replaced copy]; 
} 

@end 

Внимание: подходит только в том случае, если вы разбираете небольшое количество данных.

Источник: https://stackoverflow.com/a/16702060/1603234

0

Два других правильные ответы - это не проблема версии операционной системы, а то, что вы передается значение NULL и не поймав его.

Линия вы попали в Exception:

self.lastMessageLabel.textColor = [UIColor redColor]; 

указывает, симптом, а не причина. Я не уверен на 100%, как работает _setTextColor, но я бы сделал сильную ставку, что он работает, используя атрибут длины NSString/NSAttributedString, чтобы сделать NSRange, чтобы он знал, с чего начать применять цвет и заканчивать применение цвета. Если данные NULL, то, как упомянули другие пользователи, вы пытаетесь получить доступ к атрибуту длины для неправильного класса, вызывая потерю.

Судя по вашей трассировке стека, строки 5 (setMessage: forUser) и 6 (cellForRow ...) - это то место, где вы должны пытаться поймать значение NULL. Либо это, либо вы должны изменить свой контроллер данных, чтобы при возврате значения NULL в JSON вы заменили его на заполнитель, например «No Message».

В любом случае, ваша авария, вероятно, происходит, когда вы присваиваете значение self.lastMessageLabel.text, когда вы строите ваши клетки Tableview в cellForRow .... Проверьте NSString, которую вы используете для типа класса (isKindOfClass [NSNULL class]) и посмотрите, поможет ли это.