7

में एक दृश्य को अनदेखा करना बहुत धीमा है, मूल प्रश्न के बाद अधिक संक्षिप्त और केंद्रित प्रश्न के साथ दोबारा अनुत्तरित किया गया। शोध के एक और दिन के बाद समस्या में और अधिक अंतर्दृष्टि जोड़ना:CTCallCenter callEventHandler

मेरे ऐप प्रतिनिधि (didFinishLaunching) में, मैंने CTCallCenter पर एक कॉलइवेंट हैंडलर स्थापित किया। विचार यह है कि जब कॉलस्टेट बदलता है, तो मैं userInfo dict के साथ एक कॉलम.callState युक्त अधिसूचना पोस्ट करता हूं। मेरे विचार में, मैं इस अधिसूचना का निरीक्षण करता हूं, और जब उपयोगकर्ताइन्फो निर्देश में CTCallDisconnected का मान होता है, तो मैं एक दृश्य को अनदेखा करना चाहता हूं।

मेरी समस्या यह है कि अनदेखी पहलू, लगभग लगातार ~ 7 सेकंड ले रहा है। बाकी सब कुछ ठीक काम कर रहा है, और मुझे यह पता है क्योंकि मैं बिना किसी छिपाने से पहले और बाद में एनएसएलॉग, और उन लॉग तुरंत दिखाई देते हैं, लेकिन धूमिल दृश्य अभी भी 7 सेकंड के लिए है।

यहाँ मेरी कोड है:

appDidFinishLaunching:

 
    self.callCenter = [[CTCallCenter alloc] init]; 
    self.callCenter.callEventHandler = ^(CTCall* call) { 
     // anounce that we've had a state change in our call center 
     NSDictionary *dict = [NSDictionary dictionaryWithObject:call.callState forKey:@"callState"]; 
     [[NSNotificationCenter defaultCenter] postNotificationName:@"CTCallStateDidChange" object:self userInfo:dict]; 
    }; 

जब कोई उपयोगकर्ता एक बटन है कि एक फ़ोन नंबर डायल करता टैप करता मैं तो इस सूचना के लिए सुनने:

 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ctCallStateDidChange:) name:@"CTCallStateDidChange" object:nil]; 

फिर, ctCallStateDidChange में :

 
- (void)ctCallStateDidChange:(NSNotification *)notification 
{ 
    NSLog(@"121"); 
    NSString *callInfo = [[notification userInfo] objectForKey:@"callState"]; 
    if ([callInfo isEqualToString:CTCallStateDisconnected]) { 
     NSLog(@"before show"); 
     [self.view viewWithTag:kNONEMERGENCYCALLSAVEDTOLOG_TAG].hidden = NO; 
     NSLog(@"after show"); 
    } 
} 

मैं इस समस्या ट्रैक करने के बाद उपरोक्त कोड नमूने में अगर हालत के लिए नीचे:

 
    if ([[userInfo valueForKey:@"userInfo"] valueForKey:@"callState"] == CTCallStateDisconnected) { 

अगर मैं बस के साथ कि बदल देते हैं:

 
if (1 == 1) { 

तब दृश्य तुरंत दिखाई देता है!

बात यह है कि, एनएसएलओजी स्टेटमेंट तुरंत लॉगिंग कर रहे हैं, लेकिन दृश्य इसके अनदेखी में लगी हुई है। यह स्थिति तुरंत निष्पादित करने के लिए ब्लॉक का केवल एक हिस्सा क्यों हो सकती है, और शेष ~ 7 सेकंड प्रतीक्षा करें?

धन्यवाद!

+0

छिपाने/प्रकट करने की प्रक्रिया बहुत तेज है। समस्या आपके दृश्य की सामग्री और इसके पर्यवेक्षण के साथ है। क्या आपने उपकरण के साथ मामले को प्रोफाइल करने की कोशिश की है? पोस्ट कोड जहां आप दृश्य को कॉन्फ़िगर करते हैं जो छुपाएगा और देखेंगे छुपाए जाने के बाद इसका खुलासा किया जाएगा। – Zapko

+0

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

+0

समय प्रोफ़ाइल का उपयोग करें, यह आपको हर पल पर कॉल स्टैक दिखाएगा और प्रत्येक कार्य कितनी देर तक काम करेगा। यह निश्चित रूप से आपकी मदद करेगा – Zapko

उत्तर

10

इस के लिए अपने कोड को बदलने का प्रयास करें:

- (void)ctCallStateDidChange:(NSNotification *)notification 
{ 
    NSLog(@"121"); 
    NSString *callInfo = [[notification userInfo] objectForKey:@"callState"]; 
    if ([callInfo isEqualToString:CTCallStateDisconnected]) { 
     NSLog(@"before show"); 
     [self.view viewWithTag:kNONEMERGENCYCALLSAVEDTOLOG_TAG].hidden = NO; 
     NSLog(@"after show"); 
    } 
} 

नोट:

  • पैरामीटर एक NSNotification है, न कि एक NSDictionary
  • मैं ==
  • कोई ज़रूरत नहीं के साथ तार की तुलना नहीं होगा hidden संपत्ति
  • बदलने के लिए दृश्य डालने के लिए
  • उपयोग NO बजाय false

अद्यतन: एक विचार मिल गया: आप NSLog रों के बीच में, निम्न को आज़मा सकते कृपया,?

dispatch_async(dispatch_get_main_queue(), ^{ 
    [self.view viewWithTag:kNONEMERGENCYCALLSAVEDTOLOG_TAG].hidden = NO; 
}); 

पढ़ना CTCallCenter दस्तावेज़, यह callEventHandler पर "डिफ़ॉल्ट प्राथमिकता वैश्विक प्रेषण कतार" है, जो मुख्य कतार जहां सभी यूआई सामान होता नहीं है भेजा जाता है लगता है।

+0

धन्यवाद थॉमस। हालांकि आपके सभी सुझाव उचित और अच्छी तरह से प्राप्त हुए हैं (मैंने आपके कोड नमूने का उपयोग करने के लिए भी अपना प्रश्न अपडेट किया है), मुझे अभी भी एक ही समस्या है। दृश्य प्रकट होने से 7 सेकंड पहले। समस्या यह नहीं है कि मैं इस शर्त को पूरा नहीं कर सकता (यहां तक ​​कि मेरा कोड जिसे आपने संपादित किया है, आईएफ शर्त को संतुष्ट कर रहा था), यह है कि यह दो एनएसएलॉग के लॉग से संतुष्ट हो जाता है, लेकिन दृश्य 7 सेकंड के लिए प्रकट नहीं होता है। इसके अलावा, थोड़ा सा विषय, लेकिन जब इसे कास्ट करना आवश्यक है, और आप इसे कब छोड़ सकते हैं? – djibouti33

+0

यदि आप अपनी खुद की संपत्तियों या विधियों में से किसी एक को एक्सेस करना चाहते हैं तो आपको अपने उप-वर्ग में डालना होगा। 'छुपा '' UIView' की एक संपत्ति है, इसलिए यहां डालने की कोई आवश्यकता नहीं है। –

+0

इसके अलावा, @ थॉमस मुल्लेर को याद रखें, अगर मैं आईएफ शर्त को बदलता हूं: यदि (1 == 1), यह भी (स्पष्ट रूप से) संतुष्ट है, लेकिन सब ठीक से काम करता है। पहला लॉग लॉग, दृश्य तुरंत प्रकट होता है, और फिर दूसरा लॉग लॉग। उस विशिष्ट स्थिति के बारे में कुछ दिखने में देरी हो रही है। – djibouti33

0

ऐसा लगता है कि आपके छिपे हुए कोड में कोई समस्या नहीं है। अगर मैं आप थे, तो कॉल समाप्त होने के बाद मैं सभी कोड पर टिप्पणी करूंगा, और यह देखने के लिए कि उन्हें क्या समस्या है, उन्हें एक-एक करके असम्बद्ध करें।

+0

धन्यवाद, लेकिन यह काम नहीं कर रहा था। मेरे कॉलबैक हैंडलर में, मैंने दृश्य दिखाने के बाद सब कुछ अपरिवर्तित किया, और इसमें अभी भी 7 सेकंड की देरी है। – djibouti33

0

एचएम ... छुपे हुए संपत्ति को बदलने के बाद [yourViewController.view setNeedsDisplay] पर कॉल करने का प्रयास करें। या छुपाएं, अल्फा या addSubview का उपयोग करें: और इसके बजाय FromSuperview विधियों को हटा दें।

+0

आपके सभी सुझावों @Zapko के लिए धन्यवाद। मैंने अभी पाया है कि अगर मैं appDelegate.userInitiatedCall.callState के लिए परीक्षण की शर्तों को हटा देता हूं, वांछित के रूप में, सब ठीक दिखाई देता है। निश्चित नहीं है कि ऐप प्रतिनिधि पर एक इवर की जांच क्यों कर रही है। कोई विचार? – djibouti33

+0

आपको यह ध्यान में रखना चाहिए कि जब आप 'appDelegate.userInitiatedCall.callState == कुछ' लिखते हैं तो यह iVar की जांच नहीं कर रहा है, यह 2 विधियों को कॉल कर रहा है '[[appDelegate userInitiatedCall] callState] '। इस तरीकों का प्रदर्शन करने का समय उनकी जटिलता पर निर्भर करता है। उदाहरण के लिए, यदि आपने अभी उन्हें संश्लेषित किया है लेकिन उन्हें _nonatomic_ सेट नहीं किया है तो उन्हें _nonatomic_ वाले से अधिक करने में अधिक समय लगेगा। यदि आपके पास किसी विधि में कुछ संपत्ति के लिए कई कॉलिंग हैं तो स्थानीय मामले बनाना उचित है, आपके मामले में 'कॉल * initedCall = appDelegate.userInitiatedCall'। – Zapko

+0

घोषणाओं की जांच करें और, यदि संभव हो, तो उन सभी गुणों के कार्यान्वयन जिन्हें आप अपने आईएफएस में कई बार उपयोग करते हैं। अगर कुछ जटिल या थ्रेड सुरक्षित (परमाणु) होंगे तो यह समझ में आएगा। – Zapko

0

djibouti33,

तुम कहाँ जब कोई उपयोगकर्ता एक बटन है कि एक फ़ोन नंबर डायल करता? WillResignActive समारोह पर टैप करता सुनने के लिए इस वाक्य में कहें?

यह वाक्य -> ​​[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector (ctCallStateDidChange :) नाम: @ "CTCallStateDidChange" ऑब्जेक्ट: nil];

आपके समय के लिए धन्यवाद,

विली।

+0

फ़ोन कॉल करने के लिए उपयोगकर्ता को टैप करने वाला बटन उस लक्ष्य/क्रिया को सौंपा गया है (handleDialTap :)।हैंडलटैप के अंदर, मैं कुछ चीजें करता हूं, जिनमें से एक डायलऑट नामक एक और विधि कहलाता है:। डायलऑट के अंदर: जहां मैं ctCallStateDidChange अधिसूचना के लिए सुनना शुरू करता हूं। उम्मीद है की वो मदद करदे। – djibouti33