What is the availability of NSNotFound?
Insert availabilityOfNSNotFound == NSNotFound
joke here.
At some point when Apple was pushing mandatory 64-bit device support (iOS 8.4 SDK?), the declaration of NSNotFound
was changed from:
enum {NSNotFound = NSIntegerMax};
to
static const NSInteger NSNotFound = NSIntegerMax;
You can verify this in <Foundation/NSObjCRuntime.h>
.
The documentation was never changed, so the availability of the enum
NSNotFound
is no longer in the SDK. But as of iOS 9 and above, the static const NSInteger
NSNotFound
is available.
Although I cannot answer the true availability of NSNotFound
since I don't work for Apple (as a developer I think it's safe to use in all iOS versions since 2.0, or else a lot of Foundation classes would break since they can return NSNotFound
), you can check to see if the memory location for NSNotFound
is NULL:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
BOOL found = (&NSNotFound != NULL);
#pragma clang diagnostic pop
if (found) {
NSLog(@"meh");
}
Should I compare NSNotFound to NSInteger or NSUInteger?
You should use NSUInteger
The reason behind this is "The array index is not going to minus (i.e object at index -5)"
typedef int NSInteger;
typedef unsigned int NSUInteger;
NSInteger must be used when there are probability to get values in plus or minus.
Hope it helps.
Thanks
Why does range.location == NSNotFound mean that a word is found and not the opposite?
If I understand it correctly, that function returns true if the given word does not contain a misspelled word, so
return misspelledRange.location == NSNotFound;
makes sense.
NSNotFound not working with NSUser default
Obviously there is a misunderstanding: NSNotFound
is not equal to key is missing, it's a valid integer value.
The easiest way to keep your logic is to register the key-value pair with NSNotFound
as the default value.
As soon as possible (applicationDidFinishLaunching
or earlier) write
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *defaultValues = @{@"selectedUnit": @(NSNotFound)};
[defaults registerDefaults:defaultValues];
That means NSNotFound
is considered as default value until it's overwritten the first time. The 3 lines must be executed every time the application launches. If the app is reinstalled the default value is taken again.
Now you can use your logic in the question.
PS: You don't need to synchronize
after writing. The framework does that periodically.
NSRange not matching with NSNotFound
Looking at your logic, sender.currentTitle
is always going to be @"."
in your else statement, and so your range is always going to have a location of 0.
NSNotFound for Swift
It's simply aggregate initialization syntax for structs in C. You can use the NSRange initializer instead:
let notFoundRange = NSRange(location: NSNotFound, length: 0)
Or, perhaps more simply:
if linkRange.location != NSNotFound { ...
NSRange: range.location != NSNotFound vs. range.length 0
The two checks are not always identical. It depends on how the range was generated. Example:
NSRegularExpression *re = [NSRegularExpression
regularExpressionWithPattern:@"(?= )" options:0 error:NULL];
NSTextCheckingResult *result = [re firstMatchInString:@"hello world"
options:0 range:NSMakeRange(0, 11)];
NSLog(@"range = %@", NSStringFromRange(result.range));
The range's length is 0, but its location is 5, not NSNotFound
.
What happens when rangeOfCharacterFromSet is called?
- (void)test {
NSString *str = @"input content";
NSCharacterSet *characterSet = [NSCharacterSet decimalDigitCharacterSet];
NSRange range = [str rangeOfCharacterFromSet:characterSet];
NSLog(@"location:%ld, length:%ld", range.location, range.length);
// range.location is 9223372036854775807, in fact it is a NSNotFound which means not exists, range.length is 0
str = @"input 1";
range = [str rangeOfCharacterFromSet:characterSet];
NSLog(@"location:%ld, length:%ld", range.location, range.length);
// range.location is 6, range.length is 1
str = @"input 123";
range = [str rangeOfCharacterFromSet:characterSet];
NSLog(@"location:%ld, length:%ld", range.location, range.length);
// range.location is 6, range.length is 1
str = @"123 input 123";
range = [str rangeOfCharacterFromSet:characterSet];
NSLog(@"location:%ld, length:%ld", range.location, range.length);
// range.location is 0, range.length is 1
}
In the test, str is the receiver, when you call a method, who call who is reciever: [receiver callTheMethod]. Abount NSCharacterSet, I think the document explains clearly:
An NSCharacterSet object represents a set of Unicode-compliant characters. NSString and NSScanner objects use NSCharacterSet objects to group characters together for searching operations, so that they can find any of a particular set of characters during a search. The cluster’s two public classes, NSCharacterSet and NSMutableCharacterSet, declare the programmatic interface for static and dynamic character sets, respectively.
NSRange is the result of [str rangeOfCharacterFromSet:characterSet], it is a struct, range.location is the first index in str which is included in characterSet, it is a NSInteger type, when the str not exits a the content of characterSet it will be a very big integer, and it means NSNotFound. range.length means as the words, at here, it always is 1 unless range.location is NSNotFound.
Hope it helps.
Related Topics
How to Create a Hotspot Network in iOS App Using Swift
Suppress Warnings from Dependencies with Swift Package Manager
Swift 3: Converting Data to String Returns a Nil Value
How to Use Case Enum Comparison as a Boolean Expression
Swift: Specialize Method of Generic Class for Function Types
Big O of Accessing a String with an Index in Swift 3.0
Delay a Repeating Animation in Swiftui with Between Full Autoreverse Repeat Cycles
Use of Nspathcontrol to Represent Virtual Path
Swift:Pause and Resume Nstimer
How to Trigger Xcode's 'Update to Latest Package Versions' from Command Line
Counting Coloured Pixels on the Gpu - Theory
How to Define Static Constant in a Generic Class in Swift
Is .Playground a Swift File? Who Can 'See' It
Selectively Remove and Delete Objects from a Nsmutablearray in Swift
Is It Safe to Force Unwrap an Optional After Checking It Is Not Nil
Tap Gesture Not Working as Expected When Added to Uiview in Collectionview Cell