2

Possible Duplicate:
Program received signal: “0”. Data Formatters temporarily unavailable

I am taking above 200 OBShapedButtons on XiB and setting up the background images over there. After that I am taking the image of that particular OBShapedButton and coloring the image and setting it back again as the background of that OBShapedButton.

-(void)onTick:(NSTimer *)timer {
    //Database
    UIImage *setColor=[[UIImage alloc] init];
    for (int i=0; i<[dataArray count]; i++)
    { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        currentLevelMaleValue =[[[dataArray objectAtIndex:i] objectForKey:@"CurrentLevelMaleColor"] doubleValue];
        printf("Current val is %f",currentLevelMaleValue);
        for (OBShapedButton *obshapedCountryButtons in scrollBaseView.subviews) 
        {
            if (obshapedCountryButtons.tag==i+1) 
            {
                UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapButton:)];
                tap.numberOfTouchesRequired=1;
                tap.numberOfTapsRequired=1;
                [obshapedCountryButtons addGestureRecognizer:tap];
                [obshapedCountryButtons addTarget:self action:@selector(buttonTagTrap:) forControlEvents:UIControlEventTouchDown];
                //[obshapedCountryButtons addTarget:self action:@selector(tapButton:) forControlEvents:UIControlStateHighlighted];
                setColor=[obshapedCountryButtons imageForState:UIControlStateNormal];
                countryCode =[self getCountryColorCurrentLevel:currentLevelMaleValue];
                setColor =[setColor imageTintedWithColor:countryCode];
                [obshapedCountryButtons setImage:setColor forState:UIControlStateNormal];[pool release];
                //    [setColor release];
                //    [obshapedCountryButtons release];
                //    [tap release]; 
                //         
            }

            //  }
        }
    }
}

Now,I am getting this error[After the loop has been executed around 40 times]-

Program received signal: “0”. Data Formatters temporarily unavailable, will re-try after a 'continue'. (Unknown error loading shared library "/Developer/usr/lib/libXcodeDebuggerSupport.dylib

Receiving this warning-

Received memory warning

Then the app is getting terminated.

Note :

No object allocations.

Please help me out with some of your ideas. How should I go ahead ?

Community
  • 1
  • 1
Akshay
  • 2,973
  • 6
  • 43
  • 75
  • 1
    200 of these button might just take up to many memory, If think you will need to implement lazy loading and setup the button that are visible. – rckoenes Nov 22 '11 at 08:53
  • 1
    Actually it's a map application, so I don't think that lazy loading would be very interactive to use. – Akshay Nov 22 '11 at 08:58
  • Instantiating views within a reoccurring timer is a bad idea. Running bigger loops within a reoccurring timer on the UI-thread is a bad idea. – Till Nov 22 '11 at 09:00
  • How about using a static background image and evaluating the clicked region within a standard touch-event-handler. – Till Nov 22 '11 at 09:01
  • Till - I am not using any static background. The images are being populated using database. – Akshay Nov 22 '11 at 09:08
  • Why do you need 200 buttons? You'll do much better to put a UIGestureRecognizer on the view and hit test the coordinates. – sosborn Nov 22 '11 at 11:17
  • sosborn - Dude, I'm implementing "Maps". It would not be very easy for me to trap the co-ordinates of each country using the UIGestureRecognizer on the view. – Akshay Nov 22 '11 at 11:19
  • What is the context calling this code? Why are you **repeatedly setting up 200 UIGestureRecognizers?** (Adding insult to injury: For a single tap on a button!) Are you absolutely, definitively, 100% sure that all the buttons you are iterating over are brand new? Otherwise you'd have implemented a premium size-unlimited write-only cache for `UIGestureRecognizer`. (What does the Allocations instrument say: Is the memory consumption growing with every time your timer fires?) – danyowdee Nov 27 '11 at 12:34
  • @Brad Larson :- This is not a duplicate and the link you have given me doesn't solve my problem. Can you explain your activity? – Akshay Dec 13 '11 at 05:34

3 Answers3

3
UIImage *setColor=[[UIImage alloc] init];

is a memory leak as you are not release it. Actually the allocation is not necessary as you are assigning some other values to it. Similarly tap is also not released as you have commented that code.

A suggestion for this. Try to put this block of code in NSAutoreleasePool.

Edit:

-(void)onTick:(NSTimer *)timer {
    //Database
    UIImage *setColor;// =[[UIImage alloc] init];
    for (int i=0; i<[dataArray count]; i++)
    { 
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        currentLevelMaleValue =[[[dataArray objectAtIndex:i] objectForKey:@"CurrentLevelMaleColor"] doubleValue];
        printf("Current val is %f",currentLevelMaleValue);
        for (OBShapedButton *obshapedCountryButtons in scrollBaseView.subviews) 
        {
            NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init];
            if (obshapedCountryButtons.tag==i+1) 
            {
                UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapButton:)];
                tap.numberOfTouchesRequired=1;
                tap.numberOfTapsRequired=1;
                [obshapedCountryButtons addGestureRecognizer:tap];
                [obshapedCountryButtons addTarget:self action:@selector(buttonTagTrap:) forControlEvents:UIControlEventTouchDown];
                //[obshapedCountryButtons addTarget:self action:@selector(tapButton:) forControlEvents:UIControlStateHighlighted];
                setColor=[obshapedCountryButtons imageForState:UIControlStateNormal];
                countryCode =[self getCountryColorCurrentLevel:currentLevelMaleValue];
                setColor =[setColor imageTintedWithColor:countryCode];
                [obshapedCountryButtons setImage:setColor forState:UIControlStateNormal];[pool release];
                //    [setColor release];
                //    [obshapedCountryButtons release];
                [tap release]; 

            }
            [pool1 drain];
        }
        [pool drain];
    }
}
Ilanchezhian
  • 17,426
  • 1
  • 53
  • 55
  • As you can see the commented code(3rd line from below), I'd released it but not working. :( – Akshay Nov 22 '11 at 09:00
  • 1
    I have checked with NSAutoreleasePool code also but no luck, :( – Akshay Nov 22 '11 at 09:02
  • Not required to alloc `setColor` image. Just declare it. That is enough. `UIImage *setColor;` is enough as you are assigning some value later. – Ilanchezhian Nov 22 '11 at 09:05
  • Where you have added the autoreleasepool? Can you please update your code? – Ilanchezhian Nov 22 '11 at 09:06
  • 1
    No success, still getting the termination, same error and warning. – Akshay Nov 22 '11 at 09:07
  • Can you please edit your question with latest code? – Ilanchezhian Nov 22 '11 at 09:11
  • Adhira - Please check the updated code. – Akshay Nov 22 '11 at 09:13
  • I have updated my answer. Pl. check – Ilanchezhian Nov 22 '11 at 09:19
  • Still same - This is the console error: Data arr count from nsuserDefaults is 229Current val is 44.450000currentLevelValue 44.450000Program received signal: “EXC_BAD_ACCESS”. Data Formatters temporarily unavailable, will re-try after a 'continue'. (Can't find dlopen function, so it is not possible to load shared libraries.) (gdb) – Akshay Nov 22 '11 at 09:25
  • I guess it crashes outside of this method. If you notice the console, it prints `currentLevelValue 44.450000` after `Current val is 44.450000`. Just check where you are logging that `currentLevelValue` – Ilanchezhian Nov 22 '11 at 09:40
  • Yes, that is in another method but it isn't crashing there. I tried this also- setColor =[setColor imageTintedWithColor:[UIColor redColor]]; Instead of this - //countryCode =[self getCountryColorCurrentLevel:currentLevelMaleValue]; Still it's crashing and console says the same. – Akshay Nov 22 '11 at 09:47
  • Is it possible for you to extract this functionality into a separate project? If you could post that, it would be helpful. – Ilanchezhian Nov 29 '11 at 09:07
  • Adhira - I am afraid that I really can't do that. :( – Akshay Dec 01 '11 at 07:08
1

profile your app with Instruments to check for memory leaks.

If no leaks, then you are trying to allocate too much memory since 200 buttons may be a lot. The only solution then is to load lazily: at any moment you should have only in memory the buttons that are visible by the user.

javieralog
  • 1,337
  • 9
  • 10
  • Thanks for replying, but- 1)Checked with Instruments-No Leaks. 2)All the buttons are visible by the user at the same time. So it'd not be a very good thing to load it lazily. – Akshay Nov 22 '11 at 10:34
  • all the 200 buttons? what size is each button? – javieralog Nov 22 '11 at 14:25
  • 1
    It varies. (According to the countries shown on the Asia Pacific Map) – Akshay Nov 23 '11 at 05:00
1

Memory warnings is a method of memory management apple implemented into iOS. If the device is running low on memory, it will send out a memory warning. It expects every running app to respond to this warning by clearing as much dirty memory as possible. It will do three rounds of memory warnings. The first two levels are basic messages to clear memory. If you don't respond to them in time, or don't clear enough memory by the 3rd level your app will be terminated as it's not playing well with the iOS.

Paste in return; at the end of if (obshapedCountryButtons.tag==i+1) block. Uncomment [setColor release]; [tap release]; code. Finding object with current tag is bad idea. Replace foreach loop with some finding block.

index = [scrollBaseView.subviews indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {

    }