2010-04-07 13 views
9

क्या कोई जानता है या अच्छे लिंक हैं जो बताते हैं कि आईफोन का इवेंट लूप हुड के नीचे क्या करता है?कस्टम इवेंट लूप और UIKit नियंत्रण। ऐप्पल का इवेंट लूप क्या अतिरिक्त जादू करता है?

हम अपने ओपनजीएल-आधारित आईफोन गेम ढांचे में कस्टम इवेंट लूप का उपयोग कर रहे हैं। यह हमारे गेम प्रतिपादन प्रणाली को कॉल करता है, वर्तमान में प्रस्तुत करता है रेंडरबफर और CFRunLoopRunInMode का उपयोग करके पंप ईवेंट। विवरण के लिए नीचे दिए गए कोड को देखें।

यह अच्छी तरह से काम करता है जब हम UIKit नियंत्रण का उपयोग नहीं कर रहे हैं (एक सबूत के रूप में, Facetap, हमारे पहले रिलीज़ किए गए गेम को आजमाएं)।

हालांकि, UIKit नियंत्रणों का उपयोग करते समय, सब कुछ लगभग काम करता है, लेकिन काफी नहीं। विशेष रूप से, UIKit नियंत्रणों की स्क्रॉलिंग ठीक से काम नहीं करती है।

उदाहरण के लिए, चलिए निम्नलिखित परिदृश्य पर विचार करें।

  • हम अपने स्वयं के दृश्य के ऊपर UIImagePickerController दिखाते हैं।
  • UIImagePickerController हमारे कस्टम व्यू
  • हम अपने स्वयं के प्रतिपादन को रोकते हैं, लेकिन कस्टम इवेंट लूप का उपयोग करते रहते हैं।

जैसा कि कहा गया है, सब कुछ स्क्रॉलिंग को छोड़कर काम करता है।

  • फ़ोटो चुनना।
  • फोटो एलबम कार्यों और संक्रमण एनिमेशन को ड्रिलिंग चिकनी हैं।
  • फोटो एलबम दृश्य को स्क्रॉल करने का प्रयास करते समय, दृश्य आपकी उंगली का अनुसरण करता है।

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

अब, हम एप्पल के इवेंट लूप का उपयोग करके और एनएसटीमर कॉलबैक के माध्यम से अपना खुद का प्रतिपादन करके अपने सिस्टम के साथ बस ठीक और बेवकूफ काम करने के लिए यूआईकिट नियंत्रण प्राप्त कर सकते हैं। हालांकि, मैं अभी भी समझना चाहता हूं, आईफोन के इवेंट लूप के अंदर संभवतः क्या हो रहा है जो हमारे कस्टम इवेंट लूप में लागू नहीं किया गया है।

- (void)customEventLoop { OBJC_METHOD; 
    float excess = 0.0f; 
    while(isRunning) { 
    animationInterval = 1.0f/openGLapp->ticks_per_second(); 

    // Calculate the target time to be used in this run of loop 
    float wait = max(0.0, animationInterval - excess); 
    Systemtime target = Systemtime::now().after_seconds(wait); 

    Scope("event loop"); 

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

    // Call our own render system and present render buffer 
    [self drawView]; 
    // Pump system events 
    [self handleSystemEvents:target]; 

    [pool release]; 

    excess = target.seconds_to_now(); 
    } 
} 

- (void)drawView { OBJC_METHOD; 

    // call our own custom rendering 
    bool bind = openGLapp->app_render(); 

    // bind the buffer to be THE renderbuffer and present its contents 
    if (bind) { 
    opengl::bind_renderbuffer(renderbuffer); 
    [context presentRenderbuffer:GL_RENDERBUFFER_OES]; 
    } 
} 

- (void) handleSystemEvents:(Systemtime)target { OBJC_METHOD; 
    SInt32 reason = 0; 
    double time_left = target.seconds_since_now(); 
    if (time_left <= 0.0) { 
    while((reason = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE)) == kCFRunLoopRunHandledSource) {} 
    } else { 
    float dt = time_left; 
    while((reason = CFRunLoopRunInMode(kCFRunLoopDefaultMode, dt, FALSE)) == kCFRunLoopRunHandledSource) { 
     double time_left = target.seconds_since_now(); 
     if (time_left <= 0.0) break; 
     dt = (float) time_left; 
    } 
    } 
} 

उत्तर

4

आप NSLog[[NSRunLoop currentRunLoop] currentMode][UIScrollView setContentOffset:] से जब [UIScrollView isDecelerating] सच है आप UITrackingRunLoopMode दिखाई देगा।

सामान्य रूप से, सिस्टम मुख्य यूआई थ्रेड रन लूप पर kCFRunLoopDefaultMode के अलावा मोड का उपयोग करेगा, जिनमें से कुछ दस्तावेज हैं। पूर्ण सिस्टम व्यवहार प्राप्त करने का एकमात्र तरीका मुख्य थ्रेड पर सिस्टम रन लूप के साथ सहयोग करना है।

आप NSTimer का उपयोग करने का प्रयास कर सकते हैं और CFRunLoopRunInMode पर कॉल करने के बजाए सिस्टम को कॉल करने की अनुमति दे सकते हैं। एक NSTimer समय के साथ चलाने के लिए स्वतंत्र है, और जब कोई अन्य यूआई दिखाया नहीं जाता है तो सिस्टम रन लूप टाइमर को कॉल करने के अलावा कुछ नहीं कर रहा होगा।

विकल्प आपके कस्टमइवेंट लूप फ़ंक्शन से वापस लौटना होगा, जबकि सिस्टम नियंत्रण प्रदर्शित किए जा रहे हैं, और अपने कस्टम UI को फिर से शुरू करते समय इसे फिर से कॉल करें।

+0

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

+0

खींचा गया, धन्यवाद, रन लूप मोड सभी को समझाते हैं। हम भी एनएसटीमर आधारित दृष्टिकोण का उपयोग कर रहे हैं और इसमें तेज एनिमेशन के साथ कुछ विसंगतियां थीं। आईफोन ओएस 3.1 में कैडिसप्ले लिंक है जो समस्या से मदद कर सकता है। –

+0

किसी कारण से, मैंने आपके उत्तर को स्वीकार किए जाने के रूप में चिह्नित नहीं किया है। इस सवाल के पहले पहले एक बक्षीस था, लेकिन बाउंटी शिकार बंद होने के बाद आपने जवाब दिया और ऐसा लगता है कि स्टैक ओवरफ्लो मुझे इसके बाद स्वीकार किए गए उत्तर को चिह्नित करने से रोकता है। अजीब। –

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