2009-11-07 11 views
21

में किसी विधि से एकाधिक मान लौटाते हुए मैंने एक समान प्रश्न पूछा, लेकिन मैं इसे ठीक से काम नहीं कर सका। मैं एक आईफोन ऐप बना रहा हूं, और एक ऐसी विधि है जिसे मैं विभिन्न फाइलों से बुलाता हूं। मैंने पाया कि सबसे आसान तरीका किसी अन्य फ़ाइल में विधि बनाना होगा, और अन्य फ़ाइलों से विधि को कॉल करना होगा।उद्देश्य-सी

यहां कुछ समस्याएं हैं। मुझे कई मानों को पारित करने के बाद, विधि से कई मान वापस करने की आवश्यकता है। उदाहरण के लिए, मैं इसे पास कर रहा हूं: (int, int, int, string, string)। और इसे बदलने के बाद, उन सभी मूल्यों को वापस करने की आवश्यकता है। मुझे किसी ने इसके कोड से पता चला है:

- (NSDictionary *)EndOfTurn:(int)varTurns withFatness:(int)varFatness 
{ 
    varTurns--; 

    if (varTurns <= 0) { 
     varFatness = varFatness - 5; 
    } 
    else { 
     varFatness += 2; 
    } 

    return [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:varFatness], @"FATNESS", [NSNumber numberWithInt:varTurns], @"TURNS", nil]; 

} 

हालांकि, इस कोड काम नहीं करता है, और मैं कुछ और जानकारी चाहिए वास्तव में यह समझना महत्वपूर्ण है। आइए मान लें कि मैं इसे इन मानों को पास कर रहा हूं:

int varMoney; 
int varNumSheep; 
int varNumShepherds; 
NSString *test1; 
NSString *test2; 

इसलिए मुझे इन सभी मानों को विधि से वापस प्राप्त करने की आवश्यकता है।

मैं इसे हेडर फ़ाइल में कैसे घोषित करूं? यह एक उद्देश्य-सी फ़ाइल में होना चाहिए, लेकिन क्या आप मुझे पूरी फाइल के लिए कोड दे सकते हैं ताकि मैं देख सकूं कि यह @implementation और @end, क्या नहीं होगा। इसके अलावा, मैं इस विधि को कैसे कॉल करूं?

+12

मैं कहना है कि चाहते हैं 'withFatness' एक समारोह का एक अद्भुत टुकड़ा है। – Malaxeur

+0

आपको इस फ़ंक्शन के परिणाम को भी बनाए रखने की आवश्यकता होगी। क्योंकि जिस शब्दकोश को आप लौट रहे हैं वह सुविधा विधि से है, यह स्वत: समाप्त हो गया है, और अगर बनाए रखा नहीं जाता है तो जल्द ही गायब हो जाएगा। यानी जब आप इसे कॉल करते हैं तो आप ऐसा कुछ करेंगे: NSDictionary * myDic = [self EndOfTurn: साथ बदलता है फटनेस: मोटापा]; [myDic बनाए रखना]; –

+1

और फिर [myDic रिलीज]; जब आप अच्छे होते हैं और इसके साथ किया जाता है। –

उत्तर

9

के बाद से आप केवल सी और सी व्युत्पन्न भाषाओं में किसी भी विधि से एक मान लौट सकते हैं आप इसे अक्सर इस्तेमाल किया जब NSError वस्तुओं के साथ काम देखेंगे , आपको बस एक ही मान वापस करने की आवश्यकता है जो आपके सभी अन्य मूल्यों का प्रतिनिधित्व करती है। यह आपका नमूना कोड NSDictionary के साथ कर रहा है।

नमूना कोड सही है, भले ही यह सामान्य उद्देश्य-सी शैली के विपरीत हो।

आप हेडर फाइल में क्या घोषित सिर्फ प्रणाली की घोषणा है, वह यह है कि:

@interface MyClass : NSObject 
- (NSDictionary *)EndOfTurn:(int)varTurns withFatness:(int)varFatness; 
@end 

स्रोत फ़ाइल में, तो:

@implementation MyClass 
// code, as given above 
@end 
+0

केके, मैं कोशिश करूँगा। –

+0

ठीक है, इस फ़ंक्शन को कॉल करने के लिए वाक्यविन्यास क्या है?मैंने पहले ही हेडर फ़ाइल आयात की है, लेकिन जब मैं फ़ंक्शन को कॉल करने का प्रयास करता हूं तो यह कहता है "अपेक्षित: पहले: टोकन। यह कॉल: (NSDictionary *) एंडऑफर्न: (int) varTurns withFatness: (int) varFatness; \t मैं इसे वेरिएबल्स "varTurns" और "varFatness" –

+0

पास कर रहा हूं आपकी कॉल [ऑब्जेक्ट एंडऑफर्न: varTurns withFatness: varFatness] - (int) बिट्स केवल परिभाषा के लिए हैं, कॉल नहीं। –

59

पॉइंटर्स के रूप में मूल्यों में गुजरने के बारे में क्या?

उदाहरण के लिए:

- (void) getValuesForInt:(int *)int1 anotherInt:(int *)int2 aBool:(BOOL *)bool1 anotherBool:(BOOL *)bool2 { 
    if (*int1 == 42 && *int2 == 0) { 
    *int1 = 0; 
    *int2 = 42; 
    } 
    if (*bool1 == NO) { 
    *bool2 = YES; 
    } 
} 

तो फिर तुम इसे पसंद आह्वान कर सकते हैं:

int int1 = 42; 
int int2 = 0; 
BOOL bool1 = NO; 
BOOL bool2 = NO; 
[self getValuesForInt:&int1 anotherInt:&int2 aBool:&bool1 anotherBool:&bool2]; 
NSLog(@"int1: %d int2: %d bool1: %d bool2: %d", int1, int2, bool1, bool2); 
//prints "int1: 0 int2: 42 bool1: 0 bool2: 1" 

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

यह वस्तुओं के साथ समान रूप से अच्छी तरह से काम करता है।

NSError *error = nil; 
[anObject doSomething:foo error:&error]; 

रूप में लागू किया जा सकता है::

- (void) doSomething:(id)terrible error:(NSError **)error { 
    if ([terrible isEqual:reallyBad]) { 
    if (error != nil) { *error = [NSError errorWithDomain:@"domain" code:42 userInfo:nil]; } 
    } 
} 
+0

यह होना चाहिए * int2 == 0. इसके अलावा आपकी एनएसएलओजी लाइन पैरामीटर गुम है। –

+1

मुझे लगता है कि दूसरा समाधान थोड़ा अधिक प्रभावी है, मैंने पहले कोशिश की लेकिन यह तारों के साथ अच्छी तरह से काम नहीं कर सका। –

+0

@ क्रिस व्हाउप्स! ब्राउज़र में टाइपिंग कोड के लिए मुझे यही मिलता है। =) –

9

यदि आपके पास कई अलग अलग चीजें हैं जो जिसे किसी विधि से वापस करने की आवश्यकता है, या तो इसे एनएस डिक्शनरी में एन्सेप्लेट करें क्योंकि अन्य ने केवल कक्षा को परिभाषित करने या विचार करने पर विचार किया है। आवश्यकतानुसार, डेटा को समाहित करने के लिए आप आवृत्ति चर और गुणों की घोषणा कर सकते हैं।

ऐसी जानकारी को समाहित करने के लिए कक्षा को परिभाषित करना काफी कुशल साबित होता है और लचीलापन को अधिकतम करता है।यदि आपको अपने ऐप को दोबारा करने की आवश्यकता है, तो डेटा के संग्रह को नए फ़ील्ड प्राप्त होते हैं, बाद में सहेजे जाने की आवश्यकता होती है, या कार्यक्षमता हासिल करने की आवश्यकता हो सकती है, एक वर्ग इन परिवर्तनों को कम करेगा।

+4

+1 एक नई कक्षा बनाना। @Wayfarer: ओओपी की दुनिया को गले लगाओ। – mahboudz

+0

[कक्षाओं को परिभाषित करने के लिए ऐप्पल दस्तावेज़।] (https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/DefiningClasses/DefiningClasses। एचटीएमएल) –

+0

यह एक अच्छा विचार होगा यदि आप वर्कलोड के बारे में चिंतित नहीं हैं, खासकर फ्रेम संवेदनशील आवेदकों के लिए ations। यदि आप विकास कर रहे हैं, तो हम एक वीआर ऐप कहें, बचत की हर बिट एक लाभ होगी, इसलिए मैं व्यक्तिगत रूप से उन उदाहरणों के लिए डेवडेलांग उत्तर का उपयोग करूंगा। – Septronic

4

यदि आपको केवल आदिम मूल्यों को वापस करने की आवश्यकता है, तो एक संरचना लौटने का इष्टतम समाधान हो सकता है। आपको संकलन-समय त्रुटि जांच मिलती है (उदा। एनएस डिक्शनरी के विपरीत जहां आप अमान्य कुंजी को पढ़ने का प्रयास कर सकते हैं), जबकि कक्षा बनाने में शामिल सभी कोड/फ़ाइलों की आवश्यकता नहीं होती है।

typedef struct myStruct { 
    int varMoney; 
    int varNumSheep; 
    int varNumShepherds; 
} myStruct; 

ऐप्पल अपने कई तरीकों से भी structs का उपयोग करता है (उदा। CGPoint, CGRect)।

कारण यह वस्तुओं के साथ काम नहीं करेगा क्योंकि ARC forbids this है।

+0

मुझे यकीन है कि संरचना में ऑब्जेक्टिंग ऑब्जेक्ट्स अब एआरसी के बाद समर्थित नहीं है। किसी वर्ग या शब्दकोश का उपयोग करना शायद बेहतर होता है जैसा कि अन्य ने उल्लेख किया है, भले ही यह थोड़ा "इष्टतम" हो। – Taum

+0

@ टाम: आप सही हैं, मैंने जवाब अपडेट किया है। – Senseful

1

कुछ डिज़ाइनों में अंतिम बिंदु में एक मामूली सुधार एक संरचना होल्डिंग एनम सदस्यों का उपयोग करना है। यह आपको पहले से उल्लिखित संकलन-समय की जांच देता है, जो कि वापसी मूल्य में किसी वस्तु की तरह दिखता है, और यदि आपको बदले में मूल्यों की जांच करने की आवश्यकता है तो स्पष्ट मामलों का लाभ।

struct:

typedef struct _SIXRecorderStateChange { 
    SIXRecorderState oldState; 
    SIXRecorderState newState; 
} SIXRecorderStateChange; 

ग्राहक कोड:

SIXRecorderStateChange stateChange = [recorderState stop]; 
    if (stateChange.newState == SIXRecorderStopped) { 
... 
... 
8

आप इस प्रकार का विधि से एक से अधिक मान वापस पारित करने के लिए एक ब्लॉक बंद उपयोग कर सकते हैं। -rrh

[self heyFunctionGiveMeBackTwoValuesFromThisFruitArray:@[@"apple", @"orange", @"banana", @"apple"] findThisFruit:@"apple" closureFunction:^(int fruitCount, NSString* fruitString) 
{ 
    NSLog(@"Two values returned, int-fruitCount:%d, NSString-fruiteString:%@", fruitCount, fruitString); 
}]; 

- (void)heyFunctionGiveMeBackTwoValuesFromThisFruitArray:(NSArray*)fruitsArray findThisFruit:(NSString*)findThisFruit closureFunction:(void (^)(int fruitCount, NSString *fruitString))passBackResultsUsingThisClosure 
{ 
    NSInteger fruitsFound = 0; 
    NSString* fruitsMessage = [NSString stringWithFormat:@"No %@ Found", findThisFruit]; 
    for (NSString* string in fruitsArray) 
    { 
     if ([string compare:findThisFruit] == NSOrderedSame) 
     { 
      fruitsFound++; 
     } 
    } 
    if (fruitsFound > 0) 
    { 
     fruitsMessage = [NSString stringWithFormat:@"You have %@ on your list this many times:%d", findThisFruit, fruitsFound]; 
    } 
    passBackResultsUsingThisClosure(fruitsFound, fruitsMessage); 
} 

परिणाम: दो मूल्यों, लौटे पूर्णांक-fruitCount: 2, NSString-fruiteString: आप अपनी सूची में सेब है इस में कई बार: 2

+1

यह एक और महान उदाहरण भी है। – Septronic

-1
In Swift 4: 

func changeV(varMoney:inout Int, varNumSheep: inout Int, varNumShepherds: inout Int, test1: inout String, test2: inout String){ 
    varMoney = 10 
    varNumSheep = 10 
    varNumShepherds = 10 
    test1 = "TEST1" 
    test2 = "TEST2" 
} 
var varMoney = 1 
var varNumSheep = 1 
var varNumShepherds = 1 
var test1 = "test1" 
var test2 = "test2" 

changeV(varMoney: &varMoney, varNumSheep: &varNumSheep, varNumShepherds: &varNumShepherds, test1: &test1, test2: &test2) 

print(varNumSheep)