Re: wordRangeForRange implememtation
Re: wordRangeForRange implememtation
- Subject: Re: wordRangeForRange implememtation
- From: Ali Ozer <email@hidden>
- Date: Sat, 10 May 2008 19:45:46 -0700
- (NSRange)wordRangeForRange:(NSRange)range{
NSString *string = [NSString stringWithString:[[self string]
substringWithRange:range]];
Why do you make yet another copy of the string; you already have the
substring? Maybe you meant to make a mutable copy?
if([string hasPrefix:@" "]){
[string stringByReplacingCharactersInRange:NSMakeRange(0, 1)
withString:@""];
"string" is not mutable, but you are mutating it here. You should be
getting a compiler warning.
Ah, sorry, you are not mutating the string, but creating a copy which
you are simply discarding. So no compiler warning. You should either
hang on to the result (assign to string?), or use an NSMutableString
to start with and call replaceCharactersInRange:withString:
Other comments still apply.
Ali
Begin forwarded message:
From: Ali Ozer <email@hidden>
Date: May 10, 2008 7:42:11 PDT
To: Lincoln Green <email@hidden>
Cc: Ali Ozer <email@hidden>, email@hidden
Subject: Re: wordRangeForRange implememtation
There are a number of problems in this code...
- (NSRange)wordRangeForRange:(NSRange)range{
NSString *string = [NSString stringWithString:[[self string]
substringWithRange:range]];
Why do you make yet another copy of the string; you already have the
substring? Maybe you meant to make a mutable copy?
if([string hasPrefix:@" "]){
[string stringByReplacingCharactersInRange:NSMakeRange(0, 1)
withString:@""];
"string" is not mutable, but you are mutating it here. You should be
getting a compiler warning. Also, don't you want to check for other
"white space" characters, such as tab, etc?
range.location++;
You probably would also want to do range.length-- here; otherwise
your range now pokes outside of the original range that was passed in.
}
NSString *op = [NSString stringWithString:[self string]];
Since you said this is in an NSTextView subclass, [self string] is
the whole contents of the string; you are making a copy of it, which
could be wasteful.
int length = range.location;
Best to use NSInteger here, for longer-lasting code (but "int" isn't
wrong, under 32-bit)
int finished = 0;
BOOL would be a better choice in general (but again, "int" isn't
wrong)
while(finished != 1){ //2
if([op substringWithRange:NSMakeRange(length, 1)] == @" "){
You can compare strings for equality with ==; use ieEqual:
finished = 1;
}else{
NSLog([op substringWithRange:NSMakeRange(length, 1)]); //1
Don't NSLog a string directly; if your string happens to contain
"%", you will get into trouble (and may crash). Instead do
NSLog(@"%@", str).
length++;
}
}
range.length = length;
return range;
}
That was sort of a "micro" commentary of your code; but I haven't
done an overall examination to see whether these fixes would fix
it. To extract a word range from a string, it may be easier to use
something like NSScanner:
// Defining the words
NSCharacterSet *validWordSet = [NSCharacterSet
alphanumericCharacterSet]; // Or however you want to define words
NSCharacterSet *wordBreakSet = [validWordSet invertedSet];
// Set up a scanner
NSScanner *scanner = [NSScanner scannerWithString:yourString];
[scanner setCharactersToBeSkipped:nil]; // We will manage skipping
ourselves (since we need to find the beginning of the word)
NSString *word = nil;
NSRange range;
[scanner scanCharactersFromSet:wordBreakSet intoString:nil]; //
Skip
range.location = [scanner scanLocation]; // Beginning of the word
if ([scanner scanCharactersFromSet:validWordSet intoString:&word])
{ // Scan the word; if successful, word will contain it, and range
will contain the range
range.length = [scanner scanLocation] - range.location;
}
But better yet, NSAttributeString in AppKit has doubleClickAtIndex:
and nextWordFromIndex:forward:. These are more for text editing
purposes, not actually detecting words, but they may very well be
good enough for your usage (at least as good as the above algorithm).
Or you can use CFStringTokenizer, which does a much better job of
actually trying to recognize words in different languages.
Ali
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden