【问题标题】:Objective-C - C style string allocation leak?Objective-C - C 风格的字符串分配泄漏?
【发布时间】:2011-11-24 02:11:00
【问题描述】:

我有一个非常简单的应用程序。我从主屏幕启动了一个新视图(“学习视图”),其中显示了图像和标签。在学习视图上有一个菜单按钮和一个下一步按钮。当用户点击下一个按钮时,视图会从 C 字符串的 char * 数组中更新图像和标签。但是,当我这样做时,工具分配显示的分配数量一直在增长,当通过单击菜单按钮破坏视图时,这些分配并没有减少。如果我只是显示学习视图然后单击菜单没有问题,分配会上升然后返回到之前的级别,但是如果我单击下一步更新 label.text,则分配不会恢复。 Instruments 报告没有泄漏。以下是相关代码sn-ps:

LearnVC.h

@interface LearnVC : UIViewController {

    IBOutlet UIImageView *imageView;
    IBOutlet UILabel *labelView1;
    NSInteger page;

}
@property (retain, nonatomic) UIImageView *imageView;
@property (retain, nonatomic) UILabel *labelView1;

@property NSInteger page;

- (IBAction)handleNext;
- (IBAction) gotoMenu;

@end

LearnVC.m

#import ...

char *states[] { "Alabama", "Alaska", "Arizona", ... };
#define maxStates 50

@implementation LearnVC

@synthesize ...

- (void)viewDidLoad
{

      NSString *tstring;
      self.page = 0;


      //test!!!!
      tstring = [[NSString alloc] initWithCString:states[self.page] encoding:NSUTF8StringEncoding];
      labelView1.text = tstring;
      [tstring release];

      [super viewDidLoad];

}

- (IBAction) handleNext {

      NSString *tstring;
      self.page++;
      if (self.page > maxStates-1) {
           self.page = 0;
      }

      //test!!!!
      tstring = [[NSString alloc] initWithCString:states[self.page] encoding:NSUTF8StringEncoding];
      labelView1.text = tstring;
      [tstring release];

}

- (void)dealloc
{

      [imageView release];
      [labelView1 release];
      [super dealloc];

}

每当我更新视图而不删除(取消分配)并重新添加它时,这似乎都会发生。旧的 C 数组是否存在无法正确复制/释放的问题。或者不释放内存的 UILabel.text 属性存在一些问题?任何帮助表示赞赏。

先谢谢你,尼尔

我将它转换为使用 NSArray -

我将此添加到 .h 文件中

NSArray *statesArray;

和 @property (retain, nonatomic) NSArray *statesArray;

然后在.m文件中

在 viewDidLoad 中

NSArray *objects = [NSArray arrayWithObjects:@"Alabama", @"Montgomery",
                    @"Alaska", @"Juneau" ,..., nil];

self.statesArray = objects;

//I assume that since I didn't init it, I don't need to release objects.

labelView1.text = [self.statesArray objectAtIndex:self.page];in dealloc

[statesArray release];

然后在我的句柄下一个

labelView1.text = [self.statesArray objectAtIndex:self.page];

我遍历整个数组,退出,重新加载等。并且分配第一次爬升,但在我通过列表一次后停止爬升。 char * 数组不是这种情况,肯定有其他事情发生,哦,好吧,我只需要摆脱旧的 C 方式并坚持使用 NS/UI 类。

这似乎已经解决了。现在我将处理图像加载,看看它是否工作相同。

【问题讨论】:

  • 我感觉您省略了一些重要的代码。特别是,您对 labelView1 对象做了什么?我看到您正在使用它的 ivar(规避发布机制)。请发布代码显示您正在使用 labelView1 做什么。
  • 我怀疑您可能只是看到“开销”。有时系统会决定,例如,永久分配短字符串并重用它们,而不是在release 上释放它们。
  • @Perception,labelView1 的 text 属性和其他的一样被保留,只要 labelView1 最终被释放,text 属性也应该如此。
  • 除了前面所有的 cmets,这里真的没有很好的理由使用 C 字符串的 C 数组。你所做的只是自找麻烦。使用 NSString 的 NSArray。
  • @DanielRHicks - 如果你这么说,那么它一定是。我在您发布的代码中没有看到任何泄漏,所以您一定没问题。

标签: objective-c string memory memory-leaks


【解决方案1】:

initWithCString:encoding: 方法可能会制作您传入的 C 字符串的内部副本,但不能保证在解除分配期间释放该副本。由于您传递的 C 字符串是常量,因此永远无法释放,您可以改用 initWithBytesNoCopy:length:encoding:freeWhenDone: 来避免创建额外的副本。例如:

NSString *s = [[NSString alloc] initWithBytesNoCopy:someCString
                                             length:strlen(someCString)
                                           encoding:NSUTF8StringEncoding
                                       freeWhenDone:NO];

【讨论】:

  • 我确信它是这样的,尽管类应该足够聪明来处理它。下次我必须使用 c-strings 时我会尝试。
【解决方案2】:

此外,系统会进行大量缓存,就像每个控件都可以缓存它使用过的文本一样。我发现,如果我多次浏览该系列,然后分配停止上升,就好像它已经缓存了所有它要去的东西。退出学习视图时分配没有下降到起点,但后续运行不再添加。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2011-06-07
    • 1970-01-01
    相关资源
    最近更新 更多