Sth Abount rangeOfComposedCharacterSequencesForRange

| /

The return value of rangeOfComposedCharacterSequencesForRange: is not always as expected. This is most likely a bug in the Apple library.

If the input NSRange is {location=0, length=0}, if the string length is greater than 0, it will return {location=0, length=1}, if the string is an empty string, it will return {location=0 , length=0}.

1
2
3
4
5
(lldb) po [@"a" rangeOfComposedCharacterSequencesForRange:NSMakeRange(0,0)]
location=0, length=1

(lldb) po [@"" rangeOfComposedCharacterSequencesForRange:NSMakeRange(0,0)]
location=0, length=0

Sometimes the input parameters are obtained through logical calculation. If you rely on the return value of rangeOfComposedCharacterSequencesForRange: for further logical processing, you need to pay attention to this abnormal scenario.

This discussion on stackoverflow is also available for reference.

About NSRange

Another thing to note is that NSRange must be initialized before use.

NSRange is a structure. When the structure is not initialized, the content is unknown and will not be initialized to 0 by default. Strictly speaking, this should be knowledge of C, not just ObjC.

For some reason, initialization may be performed according to some conditions, and once initialization is missed, Crash will be caused.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
NSRange range;

BOOL condition = NO;

// some calculation of conditions
if (condition) {
// sth
range = NSMakeRange(0, 0);
}

NSString *str = @"abc";

// may boom here!
NSRange subRange = [str rangeOfComposedCharacterSequencesForRange:range];

Crash information such as

1
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'The index 4650705487073902592 is invalid'

Normally, Xcode will indicate that the variable is not initialized with a yellow warning, such as

1
Variable 'range' is uninitialized when used here

Of course, if you use Swift to code, the compilation will simply fail, which is a better thing.


Reference List: