Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

encountering numerous leaks on iphone device when using NSOperationQueue and trying to change sliders / pickers etc

encountering numerous leaks on iphone device when using NSOperationQueue and trying to change sliders / pickers etc.

I am able to change labels without an issue, but if I try to change a slider or picker both created on interface builder I get these leaks.

Leaked Object   #   Address Size    Responsible Library         Responsible Frame
GeneralBlock-16     0x1b00a0    16  GraphicsServices    GetFontNames
GeneralBlock-16     0x1aea90    16  WebCore                WebThreadCurrentContext
GeneralBlock-16     0x1aea80    16  GraphicsServices    GSFontGetFamilyName
GeneralBlock-64     0x1a7370    64  UIKit                  GetContextStack

code below

- (void)loadData {

    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                                            selector:@selector(firstRun)
                                                                              object:nil];

    [queue_ addOperation:operation];
    [operation release];
}

- (void)firstRun {

    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    [self setSliders];

    NSLog(@"firstRun method end");

    [pool drain];

}

- (void)setSliders {  

    NSMutableArray *tempArray = [[[NSMutableArray alloc]init] autorelease];
    aquaplannerAppDelegate *appDelegate = (aquaplannerAppDelegate *)[[UIApplication sharedApplication] delegate];
    tempArray = appDelegate.settingsValuesArray;

    freshMarineSegment.selectedSegmentIndex = [[tempArray objectAtIndex:0]intValue];

    for (int i = 1; i <= 20; i++ ) {
        UILabel *label = (UILabel *)[self.view viewWithTag:200+i];  // gets label based on tag  
        UISlider *slider = (UISlider *)[self.view viewWithTag:100+i];  // gets slider based on tag

        slider.value = [[tempArray objectAtIndex:i]intValue];
        label.text = [[[NSString alloc] initWithFormat:@"%@",[tempArray objectAtIndex:i]] autorelease];

        [label release];
        [slider release];
    }
}
like image 629
zambono Avatar asked Jan 07 '11 15:01

zambono


1 Answers

I'm assuming you're doing something else before setSliders for which you created the NSOperation, and you just omitted that code.

UIKit is not guaranteed to be thread safe, and you should only access your interface elements on the main thread. This is mentioned in a few places in the docs, but the most telling is in the Cocoa Fundamentals Guide:

All UIKit objects should be used on the main thread only.

So firstRun should look more like this:

- (void)firstRun {

  NSAutoreleasePool *pool = [NSAutoreleasePool new];

  // Do something important here...

  [self performSelectorOnMainThread:@selector(setSliders) withObject:nil waitUntilDone:NO];

  NSLog(@"firstRun method end");

  [pool drain];

}

Why are you using an NSMutableArray in setSliders? You're never actually changing the array, and mutable data structures can wreak havoc in threaded programming.

Also, I'd rename the setSliders method to something like updateSliders. It's a Cocoa style issue. Methods that start with "set" should be used for mutating a single instance variable/property.

like image 147
Nathan Eror Avatar answered Oct 16 '22 03:10

Nathan Eror