2009-02-18 6 views
9

पर विचार करें निम्नलिखित main() विधि है जो आप सबसे अधिक iPhone अनुप्रयोगों मिलेगा:आईफोन ऐप के मुख्य() फ़ंक्शन को कभी खत्म करने का मौका क्यों नहीं मिलता है?

int main(int argc, char *argv[]) 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    int retVal = UIApplicationMain(argc, argv, nil, nil); 
    [pool release]; 
    return retVal; 
}

है कि मैं इन (एप्पल द्वारा प्रदान की कई नमूना परियोजनाओं सहित) के साथ सिम्युलेटर चला चुके हर iPhone एप्लिकेशन में, धागा कभी नहीं बाहर निकालता है UIApplicationMain() और main() में कोई भी शेष कोड कभी निष्पादित नहीं होता है। क्या यह अपेक्षित व्यवहार है?

मैंने सत्यापित किया है कि UIApplicationMain() के बाद कथन एक डीबगर के साथ कोड के माध्यम से कभी भी चलने से नहीं चलता है। जब उपयोगकर्ता किसी एप्लिकेशन को रोकता है (उदाहरण के लिए "होम" बटन मारकर), परिणामस्वरूप स्टैक ट्रेस दिखाता है कि [UIApplication _terminateWithStatus:] अंततः कॉल किया जाता है। यह फ़ंक्शन आपके एप्लिकेशन प्रतिनिधि की applicationWillTerminate: विधि को कॉल करता है। एक बार यह खत्म हो जाने पर, [UIApplication _terminateWithStatus:] थ्रेड को मारने/बाहर निकलने लगता है।

क्या कोई यह पुष्टि कर सकता है कि main() काम करना चाहिए, या कम से कम उनकी मशीन पर एक ही व्यवहार की पुष्टि करें?

उत्तर

19

मूल प्रश्न यह था:

लघु उत्तर "क्यों नहीं एक iPhone अनुप्रयोग के मुख्य() फ़ंक्शन कभी खत्म करने के लिए एक मौका मिलता है?": इस तरह क्योंकि UIApplicationMain() कोडित है यह है कि कभी नहीं रिटर्न ।

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

यह व्यवहार NSApplicationMain फ़ंक्शन से मेल खाता है (जो UIAplplicationMain फ़ंक्शन का ऐपकिट/कोको संस्करण है)। NSApplicationMain() के लिए प्रलेखन स्पष्ट रूप से बताता है कि यह कभी वापस नहीं आएगा।

मैंने ऐप्पल को एक बग (6600198) सबमिट करने का अनुरोध किया है कि आधिकारिक दस्तावेज (और मुख्य। एम के लिए एक्सकोड टेम्पलेट) को यह बताने के लिए सही किया जाए कि UIAplicationMain() कभी वापस नहीं आती है। हालांकि यह एक कार्यात्मक समस्या नहीं है, वर्तमान टेम्पलेट और दस्तावेज़ भ्रामक हैं।

सभी इनपुट और दिमागी तूफान के लिए सभी को धन्यवाद!

+2

अपडेट: मुझे यह रिपोर्ट करने में प्रसन्नता हो रही है कि ऐप्पल ने UIAplplicationMain() के लिए आधिकारिक दस्तावेज़ीकरण को संशोधित किया और मेरी बग बंद कर दी। प्रलेखन में अब निम्न शामिल हैं: भले ही एक पूर्णांक रिटर्न प्रकार निर्दिष्ट किया गया हो, यह फ़ंक्शन कभी वापस नहीं आता है। जब उपयोगकर्ता होम बटन दबाकर एक आईफोन एप्लिकेशन को समाप्त करते हैं, तो एप्लिकेशन शून्य से तर्क के साथ निकास सिस्टम फ़ंक्शन को कॉल करके तत्काल बाहर निकलता है। " –

1

[पूल रिलीज] के बाद लॉग इन करने के लिए कुछ भी नहीं है?

+0

कि सिद्धांत जांचना आसान होना चाहिए, बस रिलीज से पहले लॉग इन करें। –

+0

मैंने यह सत्यापित करने के लिए पोस्ट करने से पहले डीबगर का उपयोग करके इसका परीक्षण किया कि थ्रेड वास्तव में UIAplplicationMain() फ़ंक्शन (यानी, NSLog() कभी निष्पादित नहीं करता है)। शायद इस सवाल में उल्लेख किया जाना चाहिए था। –

1

fprintf का उपयोग कर की कोशिश कर रहा और देखो क्या होता

int main(int argc, char *argv[]) 
{ 
    /* 
     ... 
    same as above 
     ... 
    */ 
    [pool release]; 
    char file_name = "/tmp/log" 

    FILE *file = fopen(file_name, "w"); 

    fprintf(file_name, "END\n"); 
} 

और हमें बताएं कि क्या होता है

मैं भी जांच करने के लिए सबसे आसान तरीका सोचा वापसी

में कम से एक को तोड़ने बिंदु को अनुकूल बनाने का था gdb do

b main.c:x 

जहां x रिटर्न एस की लाइन संख्या है tatement

+0

क्षमा करें, मुझे इस सवाल में उल्लेख किया जाना चाहिए था कि मैंने डीबगर में मुख्य() के माध्यम से कदम रखा है ताकि यह सत्यापित किया जा सके कि थ्रेड कभी भी UIAplicationMain() से बाहर नहीं निकलता है। यह वास्तव में प्रतीत होता है कि जब आप "होम" बटन पर क्लिक करके एक आईफोन ऐप रोकते हैं, तो अपेक्षित व्यवहार मुख्य() बाहर निकलने से पहले थ्रेड को मारना है। –

+0

अच्छी तरह से यह पुष्टि करता है कि [पूल रिलीज] का सिद्धांत लॉगगिन को रोक रहा है। – hhafez

3

प्रयास करें:

int main(int argc, char *argv[]) 
{ 
    NSLog(@"Step 0"); 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSLog(@"Step 1"); 
    int retVal = UIApplicationMain(argc, argv, nil, nil); 
    NSLog(@"Step 2"); 
    [pool release]; 
    NSLog(@"Step 3"); 
    return retVal; 
} 

हो सकता है कि पूल की रिहाई आगे लॉगिंग जिस स्थिति में आप चरण 2 प्राप्त हैं, लेकिन कदम नहीं रोक रहा है 3.

तो चरण 2 'isn टी मुद्रित नहीं किया जा रहा है, तो यह लगभग निश्चित रूप से UIAplplicationMain के साथ कुछ गलत है - ऐसा कोई मौका है कि यह वापस नहीं लौटाता है इसलिए एनएसएलओजी स्टेटमेंट्स (चरण 1.1, चरण 1.2, ...) को इसके अंदर विभिन्न बिंदुओं पर रखें और अंतिम संदेश लॉग इन करने के लिए चलाएं ।

ड्रिलिंग रखें (चरण 1.7.1, 1.7.2, .... 1.7.6.3.2, ...) - अंततः, आप सटीक रेखा को ट्रैक करेंगे (हालांकि कॉल पदानुक्रम में गहरी) जब लॉग संदेश लॉग इन होना बंद कर देते हैं और वह लाइन आपका अपराधी होगा (या तो सामान्य रूप से लौटने के बिना लॉगिंग या बाहर निकलने "बंद कर दिया जाएगा)।

आगे टुकड़ा मैं वेब पर पाया:

=====

जब आप इस लाइन का उपयोग करें:

int retVal = UIApplicationMain(argc, argv, @"MyApp", @"MyApp"); 

पहले MyApp अपने मुख्य अनुप्रयोग प्रतिनिधि वर्ग है। दूसरा वह वर्ग है जहां स्प्रिंगबार्ड स्पर्श अधिसूचनाएं भेजता है।

इसके अलावा, यदि आप एसडीके का उपयोग कर रहे हैं, और जानकारी में परिभाषित एक मुख्य निब है।कृपया, आप कॉल को

int retVal = UIApplicationMain(argc, argv, nil, nil); 

के रूप में सभी को कवर किया जाएगा जब आप अपनी xibs बनाते हैं।

=====

अब मैं iPhone विकास के बारे में पर्याप्त (विशेष रूप से xibs) पता करने के लिए नहीं पता है कि कि पिछले सा भी साधन (या आप इसे सेट करता है, तो कर दिया है सही ढंग से), लेकिन यह की तरह लगता है संकलन का एक और चरण।

हालांकि, पढ़ने से मेरा पहला विचार यह है कि स्प्रिंगबोर्ड आपके प्रतिनिधि वर्ग को कॉल करेगा जब बटन आपको कुछ करने के लिए कहने के लिए दबाए जाते हैं (जैसे कि चुपके से बंद करें)। यदि यह आपको नहीं पूछ सकता है (यानी, कोई प्रतिनिधि नहीं), तो संभवत: [UIApplication _terminateWithStatus:] के साथ फिट होने पर इसे बंद करने के अपने अधिकारों में यह संभवतः है।

विंडोज़ दुनिया में, आप शायद मुख्य विंडो पर एक छोड़ संदेश भेज देंगे, लेकिन जैसा कि मैंने कहा है, आईफोन विकास अलग हो सकता है।

फिर भी, यह जांच करने का एक तरीका है। यदि आप एक प्रदान करते हैं तो मुझे एक प्रतिनिधि को क्या कॉल किए गए थे, यह देखने में दिलचस्पी होगी।

@implementation MyApp 
- (void) applicationDidFinishLaunching:(id)unused { 
    rect = [ UIHardware fullScreenApplicationContentRect ]; 
    rect.origin.x = 0.0f; 
    rect.origin.y = 0.0f; 
    window = [ [ UIWindow alloc ] initWithContentRect: rect ]; 
    [ window makeKeyAndVisible ]; 
    view = [ [ MyAppView alloc ] initWithFrame: rect ]; 
    [ window setContentView: view ]; 
} 
- (void) dealloc { 
    [ window release ]; 
    [ view release ]; 
    [ super dealloc ]; 
} 

तो शायद dealloc() साथ एक प्रतिनिधि यह main() वापस करने के लिए बाहर निकलने के लिए हो रही करने के लिए रहस्य है: कोड स्निपेट के साथ शामिल ऊपर इस किया था। आप उसे शॉट क्यों नहीं देते? यह आपको अपने लक्ष्य के करीब ले जा सकता है भले ही यह मूल समस्या का समाधान न करे।

+0

मुझे यह उल्लेख करना चाहिए था कि मैंने डीबगर में मुख्य() के माध्यम से कदम रखा है ताकि यह सत्यापित किया जा सके कि थ्रेड UIAplicationMain() से बाहर नहीं निकलता है। उस ने कहा, मैंने स्पष्टता के लिए भी अपना परीक्षण चलाया; कंसोल में "चरण 2" और "चरण 3" प्रकट नहीं होता है। –

1

UIApplicationMain कॉल करने के बाद अपने एप्लिकेशन को लॉन्च करने के बाद (एक रनलोप स्थापित करना) कार्य करें और सभी कार्यों को मुख्य के संदर्भ के बाहर किया जाना चाहिए (यदि आपको इसे मुख्य रूप से चलाने की आवश्यकता है, तो उस बिंदु से पहले करें)। एप्लिकेशन छोड़ते समय ओएस को स्मृति सफाई करने की अनुमति देने के लिए आम तौर पर अधिक कुशल होता है।

+0

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

0

मैं वह भी लौट अनुभव नहीं किया है। और क्लिंट ने ठीक तरह से सत्यापित करने के लिए ब्रेक पॉइंट सेट किए हैं।

वारक्वार्क का एक अच्छा बिंदु है।

महान विषय। मुझे और अधिक आरामदायक महसूस करता है कि मैं अकेला नहीं हूं जिसके पास सवाल है।

संबंधित मुद्दे