2010-09-15 18 views
18

मैं कैसे जांचूं कि NSNumber ऑब्जेक्ट शून्य या खाली है या नहीं?जांचें कि क्या NSNumber खाली है

NSNumber *myNumber; 
if (myNumber == nil) 
    doSomething 

लेकिन अगर वस्तु बना दिया गया है, लेकिन वहाँ क्योंकि एक काम में विफल रहा है उस में कोई मूल्य नहीं है, मैं यह कैसे जांच कर सकते हैं:

ठीक नहीं के बराबर आसान है? इस तरह कुछ इस्तेमाल करें?

if ([myNumber intValue]==0) 
    doSomething 

वहाँ NSString उपलब्ध के लिए की तरह शून्य पर वस्तुओं के परीक्षण के लिए एक सामान्य विधि है (इस post देखें)?

उदाहरण 1

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; 
[dict setValue:@"" forKey:@"emptyValue"]; 
NSNumber *emptyNumber = [dict objectForKey:@"emptyValue"]; 

कौन सा मूल्य emptyNumber में क्या है? मैं कैसे देख सकता हूं कि emptyNumber खाली है या नहीं?

उदाहरण 2

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; 
[dict setValue:@"" forKey:@"emptyValue"]; 
NSString *myString = [dict objectForKey:@"emptyValue"]; 
if (myString == nil || [myString length] == 0) 
    // got an empty value 
    NSNumber *emptyNumber=nil; 

अगर मैं के बाद emptyNumber नहीं के बराबर करने के लिए स्थापित किया गया था इस का उपयोग क्या होता है?

[emptyNumber intValue] 

क्या मुझे शून्य मिलता है?

उदाहरण 3

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; 
[dict setValue:@"" forKey:@"emptyValue"]; 
NSNumber *myEmptyValue = [dict objectForKey:@"emptyValue"]; 
if (myEmptyValue == nil) 
    // NSLog is never called 
    NSLog(@"It is empty!"); 

इस तरह NSLog कभी नहीं कहा जाता है की तरह। myEmptyValuenil नहीं है और NSNull नहीं है। तो इसमें एक मनमाना संख्या है?

+0

@ [0.7] एक दे देंगे NSNumber जो निश्चित रूप से शून्य नहीं है, लेकिन intValue 0 वापस आ जाएगा। तो यह एक खराब परीक्षण है। – gnasher729

+0

महान विवरण के लिए उपरोक्त जो कुछ समझने में मदद करता है जो मैं डिफ़ॉल्ट से निपट रहा हूं। NSNumber * savedPin = [[NSUserDefaults standardUserDefaults] valueForKey: @ "someKey"]; एक ऑब्जेक्ट देता है जिसमें वर्ग __NSCFConstantString है और इस प्रकार शून्य की तुलना विफल रही है। धन्यवाद! –

उत्तर

12

NSValue, NSNumber ... एक मूल्य से बनाया जा करने वाले हैं और हमेशा एक पकड़ करने के लिए। 0 जैसे किसी विशिष्ट मान के लिए परीक्षण केवल तभी काम करता है जब यह वैध मानों की सीमा में न हो, जिनके साथ आप काम कर रहे हैं।

दुर्लभ मामले में जहां कोड अधिक यदि आप एक मूल्य का प्रतिनिधित्व "अवैध" या "सेट नहीं" है के साथ काम करने सीधी-सपाट है और आप nil मानक कंटेनर के साथ जैसे उपयोग नहीं कर सकते (में) आप इसके बजाय NSNull का उपयोग कर सकते हैं।

अपने पहला उदाहरण में यह हो सकता है:

[dict setValue:[NSNull null] forKey:@"emptyValue"]; 

if ([dict objectForKey:@"emptyValue"] == [NSNull null]) { 
    // ... 
} 

लेकिन ध्यान दें कि आप केवल जब तक आप nil अंतर करने के लिए की जरूरत है सम्मिलित कर सकते हैं नहीं (या निकालने) कि मूल्य (यानी कंटेनर में नहीं) और, कहते हैं, "अवैध":

if ([dict objectForKey:@"nonExistent"] == nil) { 
    // ... 
} 

दूसरे उदाहरण का सवाल है, -intValue दे आप 0 - लेकिन बस क्योंकि nil पर संदेश भेजना 0 देता है। आप 0 भी प्राप्त कर सकते हैं उदा। NSNumber के लिए जिसका intValue0 पर सेट किया गया था, जो एक मान्य मान हो सकता है।
जैसा कि मैंने पहले ही लिखा है, आप केवल कुछ ऐसा कर सकते हैं यदि 0आपके लिए मान्य मान नहीं है। आपके लिए पर ध्यान दें, जो सबसे अच्छी तरह से काम करता है वह आपकी आवश्यकताओं के आधार पर पूरी तरह से निर्भर करता है।

आप संख्या सीमा से सभी मूल्यों की जरूरत नहीं है, तो आप एक (0 या -1 या इस्तेमाल कर सकते हैं ..:

मुझे करने की कोशिश संक्षेप में प्रस्तुत करते हैं:

विकल्प # 1 ।) और -intValue/... विशेष रूप से "खाली" का प्रतिनिधित्व करने के लिए। यह स्पष्ट रूप से आपके लिए मामला नहीं है।

विकल्प # 2:

आप बस की दुकान या अगर वे हैं "खाली" कंटेनर से मूल्यों को नहीं निकालते हैं:

// add if not empty: 
[dict setObject:someNumber forKey:someKey];  
// remove if empty: 
[dict removeObjectForKey:someKey]; 
// retrieve number: 
NSNumber *num = [dict objectForKey:someKey]; 
if (num == nil) { 
    // ... wasn't in dictionary, which represents empty 
} else { 
    // ... not empty 
} 

हालांकि यह मतलब यह है कि वहाँ कोई उन कुंजियों के बीच अंतर जो खाली हैं और चाबियाँ जो कभी मौजूद नहीं हैं या अवैध हैं।

विकल्प # 3:

कुछ दुर्लभ मामलों में अपनी अधिक शब्दकोश में सभी चाबियाँ रखने के लिए और प्रतिनिधित्व करने के लिए "खाली" भिन्न मान के साथ सुविधाजनक है। यदि आप संख्या सीमा से किसी का उपयोग नहीं कर सकते हैं तो हमें NSNumber में कुछ अलग रखना होगा "खाली" की अवधारणा नहीं है। कोको पहले से ही इस तरह के मामलों के लिए NSNull है:

// set to number if not empty: 
[dict setObject:someNumber forKey:someKey]; 
// set to NSNull if empty: 
[dict setObject:[NSNull null] forKey:someKey]; 
// retrieve number: 
id obj = [dict objectForKey:someKey]; 
if (obj == [NSNumber null]) { 
    // ... empty 
} else { 
    // ... not empty 
    NSNumber *num = obj; 
    // ... 
} 

यह विकल्प अब आप के बीच अंतर करने की अनुमति देता है "खाली", "खाली नहीं" और "नहीं कंटेनर में" (जैसे अवैध कुंजी)।

+0

के लिए मुझे किन संभावनाओं पर विचार करने की आवश्यकता है, मैंने अपनी पोस्ट संपादित की। मैं इस "विशेष मामले" में खालीपन पर कैसे परीक्षण कर सकता हूं? क्या यह वैध मानों की सीमा में है? – testing

+0

खालीपन पर बाद में एनएसएनंबर ऑब्जेक्ट का परीक्षण करने के लिए आप '[NSNull null]' डाल रहे हैं। ठीक है, लेकिन मानक कंटेनर क्या हैं? मैं गारंटी नहीं दे सकता कि मेरे NSNumber ऑब्जेक्ट को कौन सा मान सौंपा गया है। इसलिए मुझे नहीं पता कि 'शून्य' या 'NSNull' कब सम्मिलित करें। मेरे उदाहरण में यह एक खाली स्ट्रिंग भी हो सकता है।क्या मुझे पहले 'ऑब्जेक्ट फोर्के' के रिटर्न वैल्यू का परीक्षण करना चाहिए यदि यह खाली स्ट्रिंग है और फिर मुझे अपने एनएसएनंबर ऑब्जेक्ट में 'शून्य' या 'एनएसएनयूएल' डालना चाहिए? मुझे लगता है कि मुझे हमेशा शून्य डालना चाहिए, जब तक कि मुझे कुछ मामलों के लिए NSNull की आवश्यकता न हो। मेरा दूसरा उदाहरण देखें। – testing

+1

@ टेस्टिंग: मानक कंटेनर कोको टच ('एनएसएआरएआरई, 'एनएस डिक्शनरी, ...) से हैं। वस्तु जा रहा है 'NSNull' के लिए पहला नमूना परीक्षण, दूसरी हो जाती है * यदि आप कंटेनर * में मूल्य डाल नहीं है - आप उन में' nil' सम्मिलित नहीं कर सकते, 'nil' का प्रतिनिधित्व करता है *" कंटेनर में नहीं " *। आपको बस "अमान्य" */* "अस्तित्व में नहीं है" * और * "कंटेनर में नहीं" * के बीच अंतर करने के लिए आपको गीलेर तय करना होगा। आपकी आखिरी वाक्य जो मैं कहता हूं उसके करीब है - या तो इसे कंटेनर में न डालें (इसलिए आपको '-objectForKey: ... ') के लिए' nil' मिलता है या' NSNull' के साथ जाना जाता है। –

3

NSNumber या तो nil है, या इसमें एक संख्या है, जो कुछ भी नहीं है। "खालीपन" एक धारणा है जो विशेष वस्तु के अर्थशास्त्र पर निर्भर करती है और इसलिए सामान्य खालीपन जांच को देखने का कोई मतलब नहीं है।

अपने उदाहरण के रूप में, वहाँ कई चीजें चल रहा हैं:

NSMutableDictionary *hash = [NSMutableDictionary dictionary]; 
[hash setObject:@"" forKey:@"key"]; 
NSNumber *number = [hash objectForKey:@"key"]; 
NSLog(@"%i", [number intValue]); 

NSLog यहाँ 0 प्रिंट होगा, लेकिन केवल क्योंकि वहाँ NSString में एक intValue विधि है। आप कुछ है कि केवल NSNumber कर सकते हैं करने के लिए संदेश को बदलते हैं, कोड विफल हो जाएगा:

NSLog(@"%i", [number unsignedIntValue]); 

यह फेंक देगा:

-[NSCFString unsignedIntValue]: unrecognized selector sent to instance 0x303c 

इसका मतलब है आप कर रहे हैं नहीं कुछ सामान्य "खाली" मूल्य मिल रहा है हैश से वापस, आप बस वहां संग्रहीत NSString प्राप्त करते हैं।

जब आपके पास खाली (== nil) NSNumber है और इसे एक संदेश भेजें, तो परिणाम शून्य होगा।

(array != nil && [array count] == 0) 
(someNumber == nil ? 0 : [someNumber intValue]) 

इस में बदल जाएगी:

([array count] == 0) 
([someNumber intValue]) 

आशा इस मदद करता है कि बस एक भाषा परंपरा है कि कोड को सरल है।

+0

तो NSNumber * test = [NSNull null] क्या करता है? –

+1

लिखित के रूप में, वह कोड ज्यादा समझ में नहीं आता है। एनएसएनयूएल सिर्फ "शून्य मूल्य का ऑब्जेक्ट संस्करण" है और इसके अस्तित्व के एकमात्र कारण संग्रह में "रिक्त" मान का प्रतिनिधित्व करना है जो सीधे शून्य को स्टोर नहीं कर सकता है। – zoul

+0

धन्यवाद, हाँ, मुझे लगता है कि मैं बस अपने दिमाग में स्पष्ट होने की कोशिश कर रहा हूं कि NSNumber –

0

NSNumber एस अपरिवर्तनीय हैं और केवल एक फैक्ट्री विधि या प्रारंभिक विधि के साथ बनाया जा सकता है जो उन्हें कुछ संख्यात्मक मान देता है। जहाँ तक मुझे पता के रूप में यह एक 'खाली' NSNumber के साथ खत्म करना संभव नहीं है जब तक आप 0.

0

गिनती यह बहुत आम है (मुझे कम से कम के लिए) एक शब्दकोश से बाहर एक वस्तु प्राप्त करने के लिए, उम्मीद करते हैं कि यह क्या हो रहा है एक NSNumber होने के लिए और फिर यह एक शून्य वस्तु वापस आ गया है। यदि ऐसा होता है और आप एक intValue करते हैं तो यह दुर्घटनाग्रस्त हो जाएगा।

मैं जो करता हूं वह सेटअप शून्य सुरक्षा है क्योंकि मुझे क्रैश से डिफ़ॉल्ट मान प्राप्त करना होगा।

एक ही रास्ता है:

-(int) intForDictionary:(NSDictionary *)thisDict objectForKey: (NSString *)thisKey withDefault: (int)defaultValue 
{ 
    NSNumber *thisNumber = [thisDict objectForKey:thisKey]; 
    if (thisNumber == nil) { 
     return defaultValue; 
    } 
    return [thisNumber intValue]; 
} 

और मैं तैरता के लिए बस यह की तरह एक है। फिर आप कम से कम अपना डिफ़ॉल्ट मान प्राप्त करें।

NSNumber *value = [self nilProtectionForNumber:[dict objectForKey:keyThatShouldBeNSNumber] withDefault:[NSNumber numberWithInt:0]]; 
0

स्विफ्ट 2.0 के साथ काम और पार्स: एक और तरीका सिर्फ शून्य सुरक्षा के लिए एक विधि बनाने के लिए ..

-(NSNumber *)nilProtectionForNumber: (NSNumber *)thisNumber withDefault: (NSNumber *)defaultNumber 
{ 
    if (thisNumber) { 
     return thisNumber; 
    } 
    else 
     return defaultNumber; 
} 

एक यह है कि आप इस तरह से फोन होता है

var myNumber = yourArray!.objectForKey("yourColumnTitle") 
    if (myNumber == nil) { 
    myNumber = 0 
     } 

मेरे मामले में, मुझे तब करना पड़ा:

let myNumberIntValue = myNumber!.intValue 
संबंधित मुद्दे