iOS7 ne renvoie que 'NSInvalidArgumentException', raison: '- :

Je travaille avec une application de livre où l'user sera en mesure de taper sur un mot, puis une partie d'un file audio sera joué pour eux contenant ce mot et le mot sera mis en évidence. Malheureusement, je reçois quelques erreurs maintenant que j'ai essayé d'optimiser le code d'être seulement iOS8 pour soutenir également iOS7.

C'est l'erreur que j'ai:

2015-06-10 10:42:50.455 Chi Shin får en hund[63976:607] selected :sammen -- <_UITextKitTextPosition: 0x7862b8b0> (28B) 2015-06-10 10:42:50.456 Chi Shin får en hund[63976:607] -[__NSCFSsortingng containsSsortingng:]: unrecognized selector sent to instance 0x78f585a0 2015-06-10 10:42:50.458 Chi Shin får en hund[63976:607] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSsortingng containsSsortingng:]: unrecognized selector sent to instance 0x78f585a0' *** First throw call stack: ( 0 CoreFoundation 0x023371e4 __exceptionPreprocess + 180 1 libobjc.A.dylib 0x020b68e5 objc_exception_throw + 44 2 CoreFoundation 0x023d4243 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275 3 CoreFoundation 0x0232750b ___forwarding___ + 1019 4 CoreFoundation 0x023270ee _CF_forwarding_prep_0 + 14 5 Chi Shin faÃär en hund 0x000ab695 -[DataViewController pageWordTapped:] + 805 6 UIKit 0x015384f4 _UIGestureRecognizerSendActions + 230 7 UIKit 0x01537168 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 383 8 UIKit 0x01538bdd -[UIGestureRecognizer _delayedUpdateGesture] + 60 9 UIKit 0x0153c13d ___UIGestureRecognizerUpdate_block_invoke + 57 10 UIKit 0x0153c0be _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 317 11 UIKit 0x015327ac _UIGestureRecognizerUpdate + 199 12 UIKit 0x011dda5a -[UIWindow _sendGesturesForEvent:] + 1291 13 UIKit 0x011de971 -[UIWindow sendEvent:] + 1021 14 UIKit 0x011b05f2 -[UIApplication sendEvent:] + 242 15 UIKit 0x0119a353 _UIApplicationHandleEventQueue + 11455 16 CoreFoundation 0x022c077f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15 17 CoreFoundation 0x022c010b __CFRunLoopDoSources0 + 235 18 CoreFoundation 0x022dd1ae __CFRunLoopRun + 910 19 CoreFoundation 0x022dc9d3 CFRunLoopRunSpecific + 467 20 CoreFoundation 0x022dc7eb CFRunLoopRunInMode + 123 21 GraphicsServices 0x0380a5ee GSEventRunModal + 192 22 GraphicsServices 0x0380a42b GSEventRun + 104 23 UIKit 0x0119cf9b UIApplicationMain + 1225 24 Chi Shin faÃär en hund 0x000dad2a main + 138 25 libdyld.dylib 0x030606d9 start + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb) 

La fonction est ci-dessous et fonctionne parfaitement dans iOS8 et c'est ainsi que j'appelle la méthode.

 UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pageWordTapped:)]; gestureRecognizer.cancelsTouchesInView = NO; [self.pageLabel addGestureRecognizer:gestureRecognizer]; 

Et la fonction.

 - (void) pageWordTapped:(UITapGestureRecognizer *)recognizer{ UITextView *textView = (UITextView *)recognizer.view; CGPoint location = [recognizer locationInView:textView]; // NSLog(@"Tap Gesture Coordinates: %.2f %.2f -- %@", location.x, location.y,textView.text); CGPoint position = CGPointMake(location.x, location.y); //get location in text from textposition at point UITextPosition *tapPosition = [textView closestPositionToPoint:position]; //fetch the word at this position (or nil, if not available) UITextRange *textRange = [textView.tokenizer rangeEnclosingPosition:tapPosition withGranularity:UITextGranularityWord inDirection:UITextLayoutDirectionRight]; NSSsortingng *tappedSentence = [textView textInRange:textRange]; NSLog(@"selected :%@ -- %@",tappedSentence,tapPosition); if (!togglePlayIsOn) { for (int i = 0; i < wordArray.count; i ++) { WordModel *wordModel = wordArray[i]; if ((wordModel.word.length - tappedSentence.length) < 3 && [wordModel.word containsSsortingng:tappedSentence]) { double timeInterval = [wordModel.endTime doubleValue] - [wordModel.startTime doubleValue]; NSTimeInterval intervalForTimer = timeInterval; NSLog(@"timeInterval :%@, %@, %f", wordModel.startTime, wordModel.endTime, intervalForTimer); [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(highlightWord:) userInfo:@{@"rangeLocation": wordModel.rangeLocation, @"rangeLength": wordModel.rangeLength} repeats:NO]; [NSTimer scheduledTimerWithTimeInterval:intervalForTimer target:self selector:@selector(unHighlightEndOfText:) userInfo:@{@"wordLength": [NSNumber numberWithInt:1]} repeats:NO]; [self playWord:[wordModel.startTime doubleValue] endTime:[wordModel.endTime doubleValue]]; return; } } } } 

Si je décommand l'instruction if (!togglePlayIsOn) , alors l'application ne if (!togglePlayIsOn) pas, donc je crois que c'est dans ce morceau de code que les erreurs se produisent.

Le problème est que containsSsortingng: est une API iOS8 et se bloque donc sous iOS7. Vous pourriez simplement replace

 [wordModel.word containsSsortingng:tappedSentence] 

avec

 [wordModel.word rangeOfSsortingng:tappedSentence].location != NSNotFound 

La méthode pour vérifier [NSSsortingng containsSsortingng:] est uniquement disponible sur iOS8, pour cela sur iOS7, vous devez:

 NSSsortingng *ssortingng = @"foo"; if ([ssortingng rangeOfSsortingng:@"oo"].location == NSNotFound) { } else { } 

Votre code se bloque parce que vous avez utilisé [wordModel.word containsSsortingng:tappedSentence] containsSsortingng est disponible dans iOS 8 et versions ultérieures. Si vous souhaitez utiliser à la fois iOS 7 et iOS 8 +, veuillez utiliser le code ci-dessous –

Implement containsSsortingng vous-même dans une catégorie en utilisant rangeOfSsortingng:

 @implementation NSSsortingng (Contains) - (BOOL)myContainsSsortingng:(NSSsortingng*)other { NSRange range = [self rangeOfSsortingng:other]; return range.length != 0; } 

J'espère que ceci vous aidera.