6

मैं पूरी तरह स्टंप्डया हूँ काम करता है, यहाँ की स्थिति है और उन्हें एक सूची के रूप में प्रदर्शित करता है। कोई समस्या नहीं।क्यों popViewController केवल हर दूसरे समय

बैटरी को संरक्षित करने के लिए, मैं सर्वर से अपना डेटा प्राप्त करने के बाद जीपीएस सेवा बंद कर देता हूं। यदि उपयोगकर्ता ऐप का उपयोग करते समय घूमता है और एक नई सूची चाहता है तो वह नेविगेशन नियंत्रक पर "ताज़ा करें" पर क्लिक करता है और सीएलएलोकेशन सेवा फिर से सक्रिय हो जाती है, सर्वर से डेटा का एक नया बैच पुनर्प्राप्त किया जाता है और तालिका को फिर से खींचा जाता है।

जबकि ऐप मेरे सर्वर से डेटा पकड़ रहा है, मैं एक कताई ग्लोब के साथ एक लोडिंग स्क्रीन लोड करता हूं जो कहता है "लोड हो रहा है, कृपया प्रतीक्षा करें" और मैं नेविगेशन बार को छुपाता हूं ताकि वे "बैक" नहीं दबा सकें।

तो, सर्वर से प्रारंभिक डेटा हड़पने बेकार ढंग से चला जाता है।

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

दूसरी बार जब मैं रीफ्रेश करता हूं तो फ़ंक्शन सामान्य रूप से काम करता है।

THIRD बार जब मैं रीफ्रेश करता हूं तो यह ऊपर की तरह विफल रहता है।

चौथा बार जब मैं ताज़ा करता हूं तो यह सामान्य रूप से काम करता है।

पांचवें बार जब मैं ताज़ा करता हूं तो यह ऊपर की तरह विफल रहता है।

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

मैं बिल्कुल परेशान हूं। कृपया सहायता कीजिए!! आपकी अंतर्दृष्टि के लिए अग्रिम धन्यवाद।

Video of the strange behavior:

प्रासंगिक कोड:

RootViewControllerMethods

- (void)viewDidLoad { 
    //Start the Current Location controller as soon as the program starts. The Controller calls delegate methods 
    //that will update the list and refresh 
    [MyCLController sharedInstance].delegate = self; 
    [[MyCLController sharedInstance].locationManager startUpdatingLocation]; 
    lv = [[LoadingViewController alloc] initWithNibName:@"Loading" bundle:nil]; 
    [self.navigationController pushViewController:lv animated:YES]; 
    [super viewDidLoad]; 
} 



- (void)updateClicked { 
    //When the location is successfully updated the UpdateCells method will stop the CL manager from updating, so when we want to update the location 
    //all we have to do is start it up again. I hope. 
    [[MyCLController sharedInstance].locationManager startUpdatingLocation]; 
    [self.navigationController pushViewController:lv animated:YES]; 
    //LV is a class object which is of type UIViewController and contains my spinning globe/loading view. 
} 



-(void)updateCells { 
    //When the Core Location controller has updated its location it calls this metod. The method sends a request for a JSON dictionary 
    //to trailbehind and stores the response in the class variable jsonArray. reloadData is then called which causes the table to 
    //re-initialize the table with the new data in jsonArray and display it on the screen. 

    [[MyCLController sharedInstance].locationManager stopUpdatingLocation]; 

    if(self.navigationController.visibleViewController != self) { 
     self.urlString = [NSString stringWithFormat:@"http://www.trailbehind.com/iphone/nodes/%@/%@/2/10",self.lat,self.lon]; 
     NSURL *jsonURL = [NSURL URLWithString:self.urlString]; 
     NSString *jsonData = [[NSString alloc] initWithContentsOfURL:jsonURL]; 
     NSLog(@"JsonData = %@ \n", jsonURL); 
     self.jsonArray = [jsonData JSONValue]; 
     [self.tableView reloadData]; 
     [self.navigationController popToRootViewControllerAnimated:YES]; 
     [jsonData release]; 
    } 
} 

CLController तरीके (यह इस tableview परियोजना के लिए आधार दृश्य है): मूल रूप से सिर्फ RootViewController

के लिए सीधे वापस सभी डेटा भेजता है
// Called when the location is updated 
- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
      fromLocation:(CLLocation *)oldLocation 
{ 
    NSLog(@"New Location: %@ \n", newLocation); 
    NSLog(@"Old Location: %@ \n", oldLocation); 
    @synchronized(self) { 
     NSNumber *lat = [[[NSNumber alloc] init] autorelease]; 
     NSNumber *lon = [[[NSNumber alloc] init] autorelease]; 
     lat = [NSNumber numberWithFloat:newLocation.coordinate.latitude]; 
     lon = [NSNumber numberWithFloat:newLocation.coordinate.longitude]; 
     [self.delegate noteLat:lat]; 
     [self.delegate noteLon:lon]; 
     [self.delegate noteNewLocation:newLocation]; 
     [self.delegate updateCells]; 
    } 
} 
+0

क्या आपने डीबगर में इन विधियों के माध्यम से कदम रखा है? यह देखने के लिए कि क्या ऑब्जेक्ट सृजन/हटाना आप अपेक्षा करते हैं, उस पर उपकरण चलाएं? क्षमा करें अगर मैं आपकी बुद्धि का अपमान कर रहा हूं, लेकिन चूंकि मुझे जल्दी से समस्या दिखाई नहीं दे रही है, तो अगली चीज़ जो मैं करूँगा वह आगे बढ़ना शुरू कर रहा है ... – mikeh

+0

क्या पॉप ऐप छोड़ देता है? ऐसा लगता है कि आप वीडियो में जीपीएस फिक्स पाने के लिए ऐप को पर्याप्त समय नहीं छोड़ रहे हैं। स्थान मैनेजर विधियों में ब्रेकपॉइंट्स सेट करने का प्रयास करें। –

उत्तर

0

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

सुनिश्चित करें कि लोडिंग व्यू कंट्रोलर क्लास में कोई स्मृति चेतावनी नहीं है। यदि कोई स्मृति चेतावनी है और आपका रूट व्यू कंट्रोलर का दृश्य जारी किया जा रहा है, तो जब आप रूटव्यू कंट्रोलर पर पॉप करते हैं तो दृश्यडिडलोड को फिर से कॉल किया जाएगा।

दृश्य में ब्रेकपॉइंट रखेंडिडलोड और अपडेट कैल्स। क्या आप वाकई लोडिंगव्यू कंट्रोलर को कहीं और नहीं बुला रहे हैं?

+0

मैंने उन दोनों कार्यों में ब्रेकपॉइंट्स डाले हैं, और लोडिंग स्क्रीन पॉप होने पर डीडलोड को कॉल नहीं किया जा रहा है। इसके अलावा मेरे कोई भी नहीं किया गया है ReemeveMemoryError कार्यों को बुलाया जा रहा है। अपडेट के बाद कोर को कोर स्टैक पर नियंत्रण रिटर्न कहा जाता है, और मुझे लगता है कि इसमें कुछ गड़बड़ हो सकता है। –

1

पहला विचार यह है कि आप CLLocationManager को StartUpdatingLocation भेजना नहीं चाहते हैं जब तक कि आप अपना लोडिंग दृश्य धक्का नहीं देते। अक्सर प्रथम स्थान प्रबंधक: didUpdateToLocation: स्थान से: संदेश तुरंत कैश किए गए जीपीएस डेटा के साथ दिखाई देगा। यह केवल तभी महत्वपूर्ण है जब आप प्रत्येक संदेश पर काम कर रहे हों और जीपीएस डेटा को फ़िल्टर न करें जैसा कि आपके नमूना कोड में दिखाया गया है। हालांकि, इससे आपके द्वारा वर्णित स्थिति का कारण नहीं बन जाएगा - इससे लोडिंग स्क्रीन फंस जाएगी।

मैंने इस तरह के अजीब व्यवहार को एक अलग परिस्थिति में अनुभव किया है जहां मैं एक अलग टैब पर स्विच करते समय रूट व्यू कंट्रोलर पर पॉप करने की कोशिश कर रहा था और सही जगह पर कॉल नहीं किया जा रहा था। मेरा मानना ​​है कि popToRootViewController को मेरे लिए दो बार बुलाया जा रहा था। मेरा संदेह यह है कि आपका लोडिंग व्यू या तो दो बार धक्का दिया जा रहा है या दो बार पॉप किया गया है।

मैं कार्यान्वयन की अनुशंसा करता हूं-viewWillAppear :, -viewDidAppear :, -viewWillDisappear: और -viewDidDisappear: आपके लोडिंग व्यू कंट्रोलर में न्यूनतम लॉगिंग के साथ।

- (void)viewWillAppear:(BOOL)animated { 
    NSLog(@"[%@ viewWillAppear:%d]", [self class], animated); 
    [super viewWillAppear:animated]; 
} 

- (void)viewDidAppear:(BOOL)animated { 
    NSLog(@"[%@ viewDidAppear:%d]", [self class], animated); 
    [super viewDidAppear:animated]; 
} 

- (void)viewWillDisappear:(BOOL)animated { 
    NSLog(@"[%@ viewWillDisappear:%d]", [self class], animated); 
    [super viewWillDisappear:animated]; 
} 

- (void)viewDidDisappear:(BOOL)animated { 
    NSLog(@"[%@ viewDidDisappear:%d]", [self class], animated); 
    [super viewDidDisappear:animated]; 
} 

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

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

0

तो, मुझे यह काम करने के लिए कभी नहीं मिला। मैं पॉपअप करने के लिए नेविगेशन नियंत्रक पर डिफ़ॉल्ट बैक बटन को अनुमति देने के बजाय प्रोग्रामर रूप से popViewController को हर बार डिवाइस पर इस व्यवहार का निरीक्षण करता हूं।

मेरा कामकाज कस्टम लोडिंग व्यू बनाना था, और इंटरनेट पर पहुंचने के कारण हर बार उस दृश्य में स्क्रीन को फ्लिप करना था। मेरी विधि हां या नहीं के एक बूलियन वैरिएबल लेती है - हाँ लोडिंग स्क्रीन पर स्विच करता है और सामान्य दृश्य पर वापस स्विच नहीं करता है। कोड यह रहा:

- (void)switchViewsToLoading:(BOOL)loading { 
// Start the Animation Block 
CGContextRef context = UIGraphicsGetCurrentContext(); 
[UIView beginAnimations:nil context:context]; 
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:self.tableView cache:YES]; 
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 
[UIView setAnimationDuration:.75]; 

// Animations 
if(loading) { 
    if (lv == nil) { lv = [[LoadingViewController alloc] initWithNibName:@"Loading" bundle:nil]; } 
    [self.view addSubview:lv.view]; 
    [self.view sendSubviewToBack:self.tableView]; 
    self.title = @"TrailBehind"; 
} 
else { 
    [lv.view removeFromSuperview]; 

} 
// Commit Animation Block 
[UIView commitAnimations]; 
//It looks kind of dumb to animate the nav bar buttons, so set those here 
if(loading) { 
    self.navigationItem.rightBarButtonItem = nil; 
    self.navigationItem.leftBarButtonItem = nil; 
    self.title = @"TrailBehind"; 
} 
else { 
    UIBarButtonItem *feedback = [[UIBarButtonItem alloc] initWithTitle:@"Feedback" style:UIBarButtonItemStylePlain target:self action:@selector(feedbackClicked)]; 
    self.navigationItem.rightBarButtonItem = feedback; 
    UIBarButtonItem *update = [[UIBarButtonItem alloc] initWithTitle:@"Move Me" style:UIBarButtonItemStylePlain target:self action:@selector(updateClicked)]; 
    self.navigationItem.leftBarButtonItem = update; 
    [feedback release]; 
    [update release]; 
} 

}

0

अपने मूल कोड को देखते हुए, मैं बहुत ज्यादा इस ब्लॉक पर शक:

- (void)viewDidLoad { 
    ... 
    lv = [[LoadingViewController alloc] initWithNibName:@"Loading" bundle:nil]; 
    [self.navigationController pushViewController:lv animated:YES]; 
    [super viewDidLoad]; 
} 

viewDidLoad हर बार नोक लोड किया जाता है कहा जाता है, जो कई भी हो सकता है कई बार, विशेष रूप से यदि आप स्मृति पर कम चलाते हैं (ऐसा कुछ ऐसा लगता है जो आपकी टिप्पणी देता है कि यह केवल डिवाइस पर होता है)। मैं अनुशंसा करता हूं कि आप -didReciveMemoryWarning लागू करें, और सुपर कॉल करने के बाद, कम से कम एक लॉग प्रिंट करें ताकि आप देख सकें कि यह आपके साथ हो रहा है या नहीं।

जो चीज मुझे उपरोक्त कोड के बारे में परेशान करती है वह यह है कि आप लगभग lv लीक कर रहे हैं, जिसका अर्थ है कि LoadingViewControllers की बढ़ती संख्या हो सकती है। आप कहते हैं कि यह एक वर्ग चर है। क्या आप वास्तव में इसका मतलब है कि यह एक आवृत्ति चर है? ivars हमेशा lv के बजाय एक्सेसर्स (self.lv या [self lv]) का उपयोग करना चाहिए। उन्हें सीधे असाइन न करें; आप लगभग हमेशा गलत करेंगे (जैसा कि आप यहां संभवतः डोंग हैं)।

0

मैं एक ही मुद्दे की खोज करते समय इस पर आया, इसलिए मुझे यकीन है कि अब तक आप अपनी समस्या का समाधान कर चुके हैं, मुझे लगा कि मैं अपना समाधान पोस्ट करूंगा यदि कोई और इसे चलाता है ...

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

वैसे भी, अपने बटन जांचें और सुनिश्चित करें कि उन्हें केवल एक ही IBAction को असाइन किया गया है। उसने मेरे लिए इसे हल कर दिया।

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