iphone - 使用 NSOperationQueue 并尝试更改 slider /选择器等时,iPhone 设备上遇到大量泄漏

标签 iphone memory-leaks instruments nsoperationqueue nsautoreleasepool

在使用 NSOperationQueue 并尝试更改 slider /选择器等时,iPhone 设备上遇到大量泄漏。

我可以毫无问题地更改标签,但如果我尝试更改在界面生成器上创建的 slider 或选择器,则会出现这些泄漏。

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

下面的代码

- (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];
    }
}

最佳答案

我假设您在创建 NSOperation 的 setSliders 之前正在执行其他操作,并且您只是省略了该代码。

UIKit 不保证线程安全,您应该只在主线程上访问界面元素。文档中的一些地方提到了这一点,但最有说服力的是《Cocoa 基础指南》:

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

所以 firstRun 应该看起来更像这样:

- (void)firstRun {

  NSAutoreleasePool *pool = [NSAutoreleasePool new];

  // Do something important here...

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

  NSLog(@"firstRun method end");

  [pool drain];

}

为什么在 setSliders 中使用 NSMutableArray?您永远不会真正更改数组,并且可变数据结构可能会在线程编程中造成严重破坏。

此外,我会将 setSliders 方法重命名为 updateSliders 之类的名称。这是一个 cocoa 风格的问题。以“set”开头的方法应该用于改变单个实例变量/属性。

关于iphone - 使用 NSOperationQueue 并尝试更改 slider /选择器等时,iPhone 设备上遇到大量泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4627098/

相关文章:

iphone - 如何使用 Facebook SDK 3.1 以弹出 View 登录 facebook,而不是通过 safari?

jakarta-ee - Java EE 对象监控工具

ios - 在 UIWebView 中加载 NSURLRequest - 堆不断增长

iphone - UIWebView 和取消点击手势

iphone - Xcode .strings 文件似乎不支持阿拉伯文本

c - C 中多维数组的内存分配问题

xcode - ios 僵尸检测

objective-c - 如何从我的 Cocoa 应用程序在终端中运行命令?

iphone - iOS CloudApp 集成

c++ - valgrind:地址 0x5111715 处无法识别的指令