NSString isEqualToString: ไม่ทำงาน

ฉันใช้รหัสนี้ในแอปของฉัน เพิ่งพบว่าไม่ถูกต้องเมื่อเปรียบเทียบภาษาเกาหลี

        for (NSString *lang in array){
        NSString *currentLang = [[MLLanguage sharedInstance] lang];
        BOOL flag = [lang isEqualToString:currentLang];
        NSLog(@"\n'%@' isEqual to '%@', %d\n%@\n%@", lang, currentLang, flag?1:0, [lang dataUsingEncoding:NSUTF8StringEncoding], [currentLang dataUsingEncoding:NSUTF8StringEncoding]);

ผลลัพธ์ที่ผิด: คำภาษาเกาหลีสองคำเปรียบเทียบว่าต่างกัน

        2012-06-19 21:16:52.681 Motilink[10188:11903] -[MLSettingLanguageViewController             loadDownloadedData][Line 50] 
        'English' isEqual to '한국어', 0
        <456e676c 697368>
        <ed959cea b5adec96 b4>
        2012-06-19 21:16:52.682 Motilink[10188:11903] -[MLSettingLanguageViewController             loadDownloadedData][Line 50] 
        '한국어' isEqual to '한국어', 0
        <e18492e1 85a1e186 abe18480 e185aee1 86a8e184 8be185a5>
        <ed959cea b5adec96 b4>
        2012-06-19 21:16:52.682 Motilink[10188:11903] -[MLSettingLanguageViewController             loadDownloadedData][Line 50] 
        '中国语' isEqual to '한국어', 0
        <e4b8ade5 9bbde8af ad>
        <ed959cea b5adec96 b4>

อันที่ถูกต้อง:

        2012-06-19 21:35:00.908 Motilink[10188:11903] -[MLSettingLanguageViewController loadDownloadedData][Line 50] 
        'English' isEqual to '中国语', 0
        <456e676c 697368>
        <e4b8ade5 9bbde8af ad>
        2012-06-19 21:35:00.909 Motilink[10188:11903] -[MLSettingLanguageViewController             loadDownloadedData][Line 50] 
        '한국어' isEqual to '中国语', 0
        <e18492e1 85a1e186 abe18480 e185aee1 86a8e184 8be185a5>
        <e4b8ade5 9bbde8af ad>
        2012-06-19 21:35:00.909 Motilink[10188:11903] -[MLSettingLanguageViewController loadDownloadedData][Line 50] 
        '中国语' isEqual to '中国语', 1
        <e4b8ade5 9bbde8af ad>
        <e4b8ade5 9bbde8af ad>

ดูเหมือนว่า: NSString ใช้การเข้ารหัสด้วยตัวเอง

ภาษาอังกฤษใช้เพียง 7 ไบต์เหมือน ASCII

จีนใช้ 9 ไบต์อาจจะเป็น utf8

แต่ในภาษาเกาหลี ปรากฏผลลัพธ์สองแบบที่แตกต่างกัน

ไม่มีใครรู้เรื่องนี้


person Galen Zhao    schedule 19.06.2012    source แหล่งที่มา
comment
-lang ส่งคืน NSString หรือไม่ ถ้าไม่เช่นนั้นพวกเขาก็จะไม่เท่ากัน บางทีคุณควรส่งทั้งสองอย่างลงใน MLLanguage แล้วลองใช้ตัวดำเนินการ isEqual:   -  person Bill Burgess    schedule 19.06.2012
comment
มันเป็นวัตถุ NSString คุณสามารถดูบันทึกได้ มีเพียงภาษาเกาหลีเท่านั้นที่ไม่ถูกต้อง   -  person Galen Zhao    schedule 19.06.2012
comment
'호텔' เท่ากับ '호텔', 0 ‹e18492e1 85a1e186 abe18480 e185aee1 86a8e184 8be185a5› ‹ed959cea b5adec96 b4› วัตถุ lang คือบรรทัดแรก บางทีวัตถุ lang อาจไม่ใช่ utf8 NSString   -  person Galen Zhao    schedule 19.06.2012


คำตอบ (1)


ปัญหาที่นี่คือคุณเปรียบเทียบสตริงที่ไม่ทำให้เป็นมาตรฐาน ใน Unicode คุณสามารถใช้อักขระได้โดยตรง หรือเขียนจากอักขระอื่นก็ได้ ตัวอย่างเช่น ในภาษาเยอรมัน มีอักขระ "ä" ซึ่งสามารถแสดงด้วยจุดโค้ด "ä" หรือลำดับของจุดโค้ดสำหรับ "¨" และ "a"

คุณมีปัญหาเดียวกันนี้กับสตริงภาษาเกาหลี: แม้ว่าสตริงเหล่านี้จะดูเหมือนกันในเอาต์พุต แต่หนึ่งในนั้นจะถูกแยกย่อย (ซึ่งนำไปสู่การแสดงข้อมูล UTF-8 ที่ยาวขึ้น) ในขณะที่อีกอันไม่ได้สลายไป

วิธีหนึ่งในการแก้ไขปัญหานี้คือทำให้สตริงทั้งหมดของคุณเป็นมาตรฐานโดยใช้ - [NSString precomposedStringWithCanonicalMapping]:

BOOL flag = [[lang precomposedStringWithCanonicalMapping] isEqualToString:
                    [currentLang precomposedStringWithCanonicalMapping]];
person Tammo Freese    schedule 19.06.2012
comment
วิธีการ compare ของ NSString ควรใช้งานได้เช่นกัน: BOOL flag = ([lang comparison:currentLang) == 0) - person arlomedia; 02.02.2016