NSString तुलना को समझना


83

निम्नलिखित दोनों तुलनाएँ सत्य का मूल्यांकन करती हैं:

1)

@"foo" == @"foo";

2)

NSString *myString1 = @"foo";
NSString *myString2 = @"foo";
myString1 == myString2;

हालांकि, निश्चित रूप से ऐसे समय हैं जहां दो NSStringएस की तुलना समानता ऑपरेटर का उपयोग करके नहीं की जा सकती है, और [myString1 isEqualToString:myString2]इसके बजाय आवश्यक है। क्या कोई इस पर कुछ प्रकाश डाला सकता है?

जवाबों:


165

==पॉइंटर तुलना के कारण काम करता है। जब आप एक निरंतर NSStringउपयोग को परिभाषित करते हैं @"", तो संकलक संदर्भ को विशिष्ट करता है। जब आपके कोड में समान स्थिरांक अन्य स्थानों पर परिभाषित किए जाते हैं, तो वे सभी स्मृति में एक ही वास्तविक स्थान पर इंगित करेंगे।

NSStringउदाहरणों की तुलना करते समय , आपको isEqualToString:विधि का उपयोग करना चाहिए :

NSString *myString1 = @"foo";
NSString *myString2 = @"foo";
NSString *myString3 = [[NSString alloc] initWithString:@"foo"];
NSLog(@"%d", (myString2 == myString3))  //0
NSLog(@"%d", (myString1 == myString2)); //1
NSLog(@"%d", [myString1 isEqualToString:myString2]); //1
NSLog(@"%d", [myString1 isEqualToString:myString3]); //1
[myString3 release];

संपादित करें:

NSString *myString3 = [[NSString alloc] initWithString:@"foo"]; 
// this is same with @"foo"

initWithString:कोई नया संदर्भ नहीं बनाता है, आपको इसकी आवश्यकता होगी initWithFormat,

NSString *myString3 = [[NSString alloc] initWithFormat:@"foo"];

6
अधिकांश संकलक भी अनुकूलन के रूप myString3में स्थिरांक "foo"को एक सूचक बनाएंगे , इसलिए आमतौर पर, इन तीनों चर एक ही मेमोरी स्थान को इंगित करेंगे। यह gcc और clang (डिफ़ॉल्ट विकल्पों के साथ) दोनों के लिए सही है। : इस संकलन का प्रयास करें gist.github.com/578568
mipadi

और इसलिए मैं NSString वैरिएबल को बिल्कुल @ @ की तरह व्यवहार कैसे कर सकता हूं? कारण मैं पूछ बी / मेरी कोड में ग अभी स्थिर है @ ".." काम करता है, लेकिन यह रूप में जल्द ही मैं एक NSString चर के साथ बदलने के रूप में दुर्घटनाओं .. देखने के लिए यहाँ
abbood

2
+1, बस जोड़ने के लिए: isEqual:वास्तव में एक पूर्ण स्ट्रिंग तुलना करता है और उसी परिणाम को वापस करता है isEqualToStringक्योंकि NSObject प्रोटोकॉल संदर्भ और NSString वर्ग संदर्भ स्पष्ट रूप से निर्दिष्ट करता है (क्रमशः): "यदि दो वस्तुएं समान (द्वारा -isEqual:) हैं तो उनके पास समान होना चाहिए हैश मान "और" यदि दो स्ट्रिंग ऑब्जेक्ट समान हैं (जैसा कि isEqualToString: विधि द्वारा निर्धारित किया गया है), उनके पास समान हैश मान होना चाहिए। "
एपीमेरा

13

समानता ऑपरेटर ==केवल सूचक पते की तुलना करता है। जब आप शाब्दिक @""वाक्य रचना का उपयोग करके दो समान तार बनाते हैं , तो संकलक पता लगाएगा कि वे समान हैं, और केवल एक बार डेटा संग्रहीत करते हैं। इसलिए, दो संकेत एक ही स्थान पर इंगित करते हैं। हालांकि, अन्य साधनों द्वारा बनाए गए तार में समान डेटा हो सकता है, फिर भी विभिन्न मेमोरी स्थानों पर संग्रहीत किया जा सकता है। इसलिए, आपको हमेशाisEqual: तार की तुलना करते समय उपयोग करना चाहिए ।

ध्यान दें कि isEqual:और isEqualToString:हमेशा समान मान लौटाएं, लेकिन isEqualToString:तेज है।


2
यह भी ध्यान दें कि isEqualToString: यदि कोई पैरामीटर इसके पास है, तो इसका अपवाद होगा nil। तो अगर कोई मौका है जो आप एक नील स्ट्रिंग की तुलना कर रहे हैं, तो आपको या तो पहले एक नील जांच करनी चाहिए या उपयोग करना चाहिएisEqual:
सैंडी चैपमैन

10

==स्मृति में स्थानों की तुलना करता है। ptr == ptr2अगर वे दोनों एक ही मेमोरी लोकेशन की ओर इशारा करते हैं। यह स्ट्रिंग स्थिरांक के साथ काम करने के लिए होता है क्योंकि संकलक समान स्ट्रिंग स्थिरांक के लिए एक वास्तविक स्ट्रिंग का उपयोग करने के लिए होता है । यह नहीं होगा यदि आप एक ही सामग्री के साथ चर है काम करते हैं, क्योंकि वे विभिन्न मेमोरी स्थानों को इंगित करेंगे; isEqualToStringऐसे मामले में उपयोग करें ।


क्या आप इसका उदाहरण दे सकते हैं कि आपका क्या मतलब है "अगर यह आपके पास समान सामग्रियों के साथ चर है तो काम नहीं करेगा"
Logicsaurus Rex

6

कोको स्ट्रिंग्स में NSString की isEqualToString:विधि का उपयोग करके तुलना की जाती है।

पॉइंटर तुलना आपके मामले में काम करती है क्योंकि कंपाइलर एक वस्तु को इंगित करने के लिए दो स्ट्रिंग शाब्दिकों को मर्ज करने के लिए पर्याप्त कोमल है। इस बात की कोई गारंटी नहीं है कि दो समान तार एक NSStringउदाहरण साझा करते हैं ।


क्या आपके पास इसका कोई आधिकारिक संदर्भ है? "कोई गारंटी नहीं है कि दो समान तार एक NSString उदाहरण साझा करते हैं।"
लोगिक्सॉरस रेक्स

@ user3055655 मुझे एक संदर्भ की आवश्यकता नहीं है: आप आसानी से कोड लिख सकते हैं जो NSStringसमान सामग्री के साथ दो अलग-अलग उदाहरण बनाता है:[NSMutableString string] != [NSMutableString string]
निकोलाई रुहे

@ user3055655 यदि आपका मतलब है कि मेरा दावा स्ट्रिंग शाब्दिकों के लिए सही नहीं है: दो बंडलों से शाब्दिक प्रयास करें (जैसे एक ऐप और इसके परीक्षण बंडल)।
निकोलाई रुहे

मैं सिर्फ सहकर्मियों को दिखाने के लिए कुछ करना चाहता था। मैं उत्परिवर्ती तारों के बराबर होने की उम्मीद नहीं करूंगा, लेकिन NSString के दो उदाहरणों की घोषणा करना और कुछ @ "स्ट्रिंग मान" निर्दिष्ट करना हमेशा ==कार्यक्षमता की गारंटी देता है। हालाँकि, यदि आप एक NSString को डिलिवर करते हैं, तो एक मान असाइन करें, और फिर एक और NSString को इस तरह से डिलीट करें, NSString stringWithFormat:तो आपको वास्तव में दो अलग-अलग स्ट्रिंग्स ==मिलेंगे जो विफल हो जाएंगे। आपने कहा कि इस बात की कोई गारंटी नहीं है कि दो NSString (NSMutableString) उदाहरण एक NSString उदाहरण साझा नहीं करेंगे, और मैंने बस पूछा कि क्या आपके पास उस दावे का कोई प्रमाण है तो मैं इसे साझा कर सकता हूं।
लोगिक्सॉरस रेक्स

@ user3055655 जैसा कि मैंने कहा, अलग बंडलों से शाब्दिक प्रयास करें।
निकोलाई रुहे

3

स्ट्रिंग तुलना के लिए सरोगेट के रूप में पता तुलना कैसे पता चलेगी एक उदाहरण:

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSString *s1 = @"foo";
    NSString *s2 = @"foo";
    NSString *s3 = [[[NSString alloc] initWithString:@"foo"] autorelease];
    NSMutableString *s4 = [NSMutableString stringWithString:@"foobar"];
    [s4 replaceOccurrencesOfString:@"bar"
                        withString:@""
                           options:NSLiteralSearch
                             range:NSMakeRange(0, [s4 length])];

    NSLog(@"s1 = %p\n", s1);
    NSLog(@"s2 = %p\n", s2);
    NSLog(@"s3 = %p\n", s3);
    NSLog(@"s4 = %p\n", s4); // distinct from s1

    NSLog(@"%i", [s1 isEqualToString:s4]); // 1

    [pool release];

0

इस उदाहरण को देखें:

NSString *myString1 = @"foo";
NSMutableString *myString2 = [[NSMutableString stringWithString:@"fo"] stringByAppendingString: @"o"];

NSLog(@"isEquality: %@", ([myString1 isEqual:myString2]?@"+":@"-")); //YES
NSLog(@"isEqualToStringity: %@", ([myString1 isEqualToString:myString2]?@"+":@"-")); //YES
NSLog(@"==ity: %@", ((myString1 == myString2)?@"+":@"-")); // NO

इसलिए, संकलक का उपयोग करने की संभावना है, यह ई-टालस्ट्रीमिंग विधि का उपयोग करने के लिए है। यह NSString के और डाइरेक्शन पॉइंटर्स के लिए है, हालांकि यह नहीं था। और संकेत अलग हैं, जैसा कि आप देखते हैं।


-1
  NSString *str1=[NSString stringWithFormat:@"hello1"];
    NSString *str2=[NSString stringWithFormat:@"hello1"];
    NSString *str3 = [[NSString alloc] initWithString:@"hello1"];




// == compares the pointer but in our example we are taking same string value to different object  using @  so it will point to same address so output will be TRUE condition
    if (str1==str2) {
        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");
    }


    // == compares the pointer but in our example we are taking same string value to different object but we have allocated different string so both object will pount to different address so output will be FALSE condition
    if (str1==str3) {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }


  // compare:= compares the values of objects so output will be TRUE condition
    if ([str1 compare:str3]== NSOrderedSame) {
        NSLog(@"Both String are equal");

    }
    else{
        NSLog(@"Both String not are equal");

    }


    // isEqual compares the values of objects so output will be TRUE condition

    if ([str1 isEqual:str2]) {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }

    // isEqual compares the values of objects so output will be TRUE condition

    if ([str1 isEqual:str3]) {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }


    // isEqualToString compares the values of objects so output will be TRUE condition
    if ([str1 isEqualToString:str2]) {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }


    // isEqualToString compares the values of objects so output will be TRUE condition
    if ([str1 isEqualToString:str3]) {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }

    // == compares the pointers since we have initialized the same value to first object so the pointer be be same for same value so output will be TRUE condition
    if (str1==@"hello1") {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.