Data Formatters temporarily unavailable, will re-try after a 'continue'

前端 未结 4 1473
灰色年华
灰色年华 2020-12-11 20:53

Here is the error message I get:

ContactsWithPN - start loop
Program received signal:  “0”.
Data Formatters temporarily unavailable, will re-try after a \'co         


        
4条回答
  •  鱼传尺愫
    2020-12-11 21:16

    First thing is that you have memory leaks in your code... Fix that like this

    +(NSArray *) contactsWithPhoneNumbers{
        NSArray *contacts = [ABContactsHelper contacts];
        NSMutableArray *rv = [[NSMutableArray alloc] init];
    
        NSLog(@"ContactsWithPN - start loop");
        for (int i = 0; i< [contacts count] ; i++) {
            ABContact * c = (ABContact*)[contacts objectAtIndex:i];
            ABContact * fullContact = [ABContact  contactWithRecordID:[c recordID]];
    
            if ([[fullContact phoneArray] count] > 0) {
                [rv addObject:fullContact];
            }
        }
    
        NSLog(@"ContactsWithPN - end loop");
        NSArray *ret = [[NSArray alloc] initWithArray:rv];
        //You need to release rv since you dont need it any more as you have copied the contents to a new array ( this itself is a waste ) so you must release the old array
        [rv release];
    
        //Now when you return the array you must still not hold object ownership since the function dies after returning so you give it a delayed release which kicks in when the autorelease is flushed.
        return [ret autorelease];
    }
    

    Normally autorelease is flushed at certain times decided by the OS however you can create your own pool to make sure that you don't waste resources. So Ideally you will make the call like this

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSArray *contactArray = [[self contactsWithPhoneNumbers] retain];
    [pool drain];
    //This will release the object ownership held by the function
    

    Finally so you do all this and you don't have memory leaks but you still get this error. The answer because the memory warning didn't get to you just as @tc. has said. So the simple answer is that the main run loop was clogged. What you can do is maybe do this operation in a separate thread to make sure that the main loop is not clogged... If you are on iOS 4+ you can do this easily by

    dispatch_queue_t otherQueue = dispatch_queue_create("com.company.otherqueue", NULL);
    dispatch_async(otherQueue, ^{
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        NSArray *contactArray = [[self contactsWithPhoneNumbers] retain];
        [pool drain];
    }
    dispatch_release(otherQueue);
    

    Now this necessarily does not mean that it will create a new thread however the os will manage the queue such that the main queue does not get blocked and you will receive the memory warning. From then on you must release the memory and make sure you dont go over.

提交回复
热议问题