2014-12-09 8 views
0

나는이 문제에 대한 해답을 찾고 있었지만 문제를 해결하는 방법을 아직 풀지 못했습니다. 이 -[NSNull length]: unrecognized selector sent to instance 및이 [NSNull length]: unrecognized selector sent to instance 0x43fe068이 도움이되지 않았습니다.iOS 8이 작동하지만 iOS 7이 - [NSNull 길이]와 충돌 함 : 인식 할 수없는 선택기가 인스턴스로 전송 됨

Parse 백엔드가있는 채팅 앱에서 작업 중이며 채팅 메시지에 타임 스탬프 문제가 발생하여 순서가 어긋나고 있으므로 Parse 데이터베이스에서 순서가 잘못된 행을 삭제했습니다. 데이터 브라우저. 내가이 앱을 테스트했을 때, 내 iPhone 6 Plus 및 iOS 8을 실행하는 iPhone 6 시뮬레이터에서 문제를 해결하는 것처럼 보였습니다. 그러나 iOS 7을 실행하는 iPhone 5에서 동일한 채팅방을 열면 앱이 계속 충돌합니다. 다음 오류.

-[NSNull length]: unrecognized selector sent to instance

나는 아무 생각이 왜 행이는 아이폰 OS 7 일이 왜 원인이 없을 것입니다 및 삭제가? All Exceptions Breakpoint를 설정하고 여기 스크린 샷과 함께 문제가되는 줄을 표시합니다.

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

편집 2 : 나는 닉 록우드 https://github.com/nicklockwood/NullSafe에서 NSNullSafe을 시도하고는 개인 편지함이 충돌없이 열 수와 NSNull 길이 오류가 과거의 저를 얻을 수 있지만 그건 그냥 마스크에게 문제를 생각하고 나는 여전히 '돈 iOS 8에서는 충돌이 발생하지 않았지만 iOS 7에서는 충돌이 발생했는지 알 수 없습니다.

답변

1

두 가지 작동 시스템의 차이점과 관련이 있다고 생각하지 않습니다.
크래시가 분명합니다. 처리 할 수없는 클래스 NSNUll의 개체에 메시지를 보내고 있습니다.
일반적으로 구문 분석이나 웹 서비스를 사용한다는 사실 때문에이 객체는 백엔드에서 JSON으로 null으로 생성되었고 JSON 구문 분석을 통해 NSNull 객체로 변환되었다고 생각됩니다.
구문 분석 수준에서 NSNull 개체를 처리하는 방법을 찾아야합니다. 당신이 다음 API (서버) 측에서 그것을 알아낼 수없는 경우

+0

방금 ​​추가 코드로 게시물을 업데이트하여 호출되는 코드의 NSNull 부분을 볼 수 있습니다. –

0

@Andrea 여기에 어떤 NSNull 개체를 제거하고 앱이 충돌하지 것이다 NSDictionaryNSArray의 종류이다, 맞습니다.

@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

다른 두 답변이 정확한지 -이 OS 버전의 문제가 아니라, 오히려 당신이 NULL 값을 전달되고 있으며, 그것을 잡는되지 않습니다.

당신이 예외에 잡힌 라인 :

self.lastMessageLabel.textColor = [UIColor redColor]; 

는 증상이 아닌 원인을 나타내는 것입니다. 100 % 확실하지 _setTextColor 실제로 작동하는지,하지만 NSString/NSAttributedString 길이 특성을 사용하여 NSRange 있도록 색 적용 및 색 적용 적용 할 위치를 알고 있도록 작동하도록 강한 내기 걸릴 것입니다. 데이터가 NULL 인 경우 언급 된 다른 사용자와 마찬가지로 잘못된 클래스의 길이 속성에 액세스하려고 시도하여 충돌을 일으 킵니다.

스택 추적에서 5 행 (setMessage : forUser)과 6 (cellForRow ...)은 NULL 값을 잡으려고 시도해야하는 곳입니다. 그 중 하나 또는 데이터 컨트롤러를 수정하여 NULL 값이 JSON에서 다시 전달 될 때 "No Message"와 같은 자리 표시 자로 바꿔야합니다. 당신이 cellForRow에있는 tableView 세포를 구축 할 때 ... self.lastMessageLabel.text을 값을 할당 할 때 어느 속도에서

, 당신의 충돌은 아마 일어나고있다. 클래스 형식 (isKindOfClass [NSNULL 클래스])에 사용하는 NSString을 확인하고 이것이 도움이되는지 확인하십시오.