ToIndex は指定したインデックスの【前】まで。(つまり指定したインデックスは含まれない)
FromIndex は指定したインデックス【から】。(つまり指定したインデックスを含む)
Range は指定したインデックス【から】指定した【文字数分】。(第一引数を含めて第二引数分)
NSString *hoge = @"0123456789";
[hoge substringToIndex:1] : 0
[hoge substringFromIndex:4] : 456789
[hoge substringWithRange:NSMakeRange(3, 6)] : 345678
NSString *piyo = @"0";
[piyo substringToIndex:1] : 0
[piyo substringFromIndex:4] : // エラー
[piyo substringWithRange:NSMakeRange(3, 6)] : // エラー
NSString *fuga = @"0123456789";
[fuga substringToIndex:9999] : // エラー
[fuga substringFromIndex:\-5] : // エラー
[fuga substringWithRange:NSMakeRange(3, 50)] : // エラー
NSString *neko = @"012345";
[neko substringToIndex:neko.length - 1] : 01234
[neko substringToIndex:neko.length] : 012345
[neko substringToIndex:neko.length + 1] : // エラー
ToIndex の仕様が気持ち悪いのは自分だけか?(なぜ指定したインデックスが含まれないのか?)