0

我已将以下变量声明为实例变量并在我的 m 文件中使用它,但是我收到了警告。

TransparentToolbar *tools;

在线分配的对象的潜在泄漏...

例如,我尝试为它创建一个属性..

@property (nonatomic, retain) TransparentToolbar *tools;

并合成并释放它,但我的视图在 dealloc 结束时崩溃。

我究竟做错了什么 ?

在 pickerSortingDataCurrent 上编辑相同的警告...

h
@interface myViewController : UIViewController <UIActionSheetDelegate, 
    UIPickerViewDelegate, UIPickerViewDataSource, UITableViewDelegate, 
    UITableViewDataSource, MFMailComposeViewControllerDelegate> {

    TransparentToolbar *tools;

    NSArray *pickerSortingDataCurrent;
}
@property (nonatomic, retain) TransparentToolbar *tools;
@property (nonatomic, retain) NSArray *pickerSortingDataCurrent;

m
@synthesize pickerSortingDataCurrent;
@synthesize tools;

- (void)viewDidLoad {
    [super viewDidLoad];

    tools = [[[TransparentToolbar alloc] 
           initWithFrame:CGRectMake(0, 0, 70, 44.01)] autorelease];
    tools.barStyle = UIBarStyleBlackOpaque;

    self.pickerSortingDataCurrent = [[NSArray alloc] initWithObjects:
      @"Next Date Ascending", 
      @"Next Date Descending", nil];     // removed some items here
}

- (void)dealloc {
    [tools release];
    [pickerSortingDataCurrent release];
    [super dealloc];
}

啊啊我有自动释放....但这并不能解决pickerSortingDataCurrent ...

编辑...

#import "TransparentToolbar.h"

@implementation TransparentToolbar

- (void)drawRect:(CGRect)rect {
    // do nothing in here
}

- (void) applyTranslucentBackground
{
    self.backgroundColor = [UIColor clearColor];
    self.opaque = NO;
    self.translucent = YES;
}

- (id) init
{
    self = [super init];
    [self applyTranslucentBackground];
    return self;
}

// Override initWithFrame.
- (id) initWithFrame:(CGRect) frame
{
    self = [super initWithFrame:frame];
    [self applyTranslucentBackground];
    return self;
}

@end

进一步编辑 在此处输入图像描述

4

3 回答 3

5

如果您定义@property,那么通常在您访问类中的 ivar 时,您使用 getter/setter,无论是点表示法还是标准方法调用。

点符号

id localyMyVar = self.myVar;
self.myVar = @"A string";

标准方法调用

id localMyVar = [self myVar];
[self setMyVar:@"A string"];

如果您总是显式地使用这些 getter 和 setter,那么您几乎不需要在代码中的任何地方调用 releasedealloc或重写setMyVar:方法。这样做可以在有限的地方进行内存管理。如果您开始释放并保留自己,那么当您刚开始时,事情可能会有点复杂。

更新

@bbum 为您提供了答案,但我认为您也会受益于更加一致的编码。

例如,在您直接分配给 ivar 而不使用 setter 的违规行之前。保持一致并使用您花时间合成的 setter/getter。我会重写

tools = [[[TransparentToolbar alloc] 
       initWithFrame:CGRectMake(0, 0, 70, 44.01)] autorelease];
tools.barStyle = UIBarStyleBlackOpaque;

TransparentToolbar *tmpTools = [[TransparentToolbar alloc] initWithFrame:CGRectMake(0, 0, 70, 44.01)];
tmpTools.barStyle = UIBarStyleBlackOpaque;
self.tools = tmpTools;
[tmpTools release]; tmpTools = nil;

您的init方法并没有真正遵循指南,或者您应该检查self实际设置的内容,因此它应该类似于:

- (id)init
{
    self = [super init];
    if (self) {
        [self applyTranslucentBackground];
    }
    return self;
}

更新

您在这里看到的内存泄漏:

self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.tools];

是因为您查看UINavigationItem的文档,您会看到它rightBarButtonItem被声明为retain

@property(nonatomic, retain) UIBarButtonItem *rightBarButtonItem

因此,该调用self.navigationItem.rightBarButtonItem将对您传入的对象进行 +1 保留,然后您将进行分配/初始化,这是另一个 +1 保留。当UINavigationItem它被释放时,它将释放它的保留,但仍然会有你原来的保留。

修复:

UIBarButtonItem *rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.tools];
self.navigationItem.rightBarButtonItem = rightBarButtonItem;
[rightBarButtonItem release]; rightBarButtonItem = nil;
于 2011-11-10T20:31:19.620 回答
1
self.pickerSortingDataCurrent = [[NSArray alloc] initWithObjects:
  @"Next Date Ascending", 
  @"Next Date Descending", nil];     // removed some items here

+1 保留计数用于 +alloc,+1 保留计数用于分配给retain @property.

将其重写为:

NSArray *labels = [[NSArray alloc] initWithObjects:
  @"Next Date Ascending", 
  @"Next Date Descending", nil];
self.pickerSortingDataCurrent = labels;
[labels release];

(或者你可以使用autorelease

于 2011-11-10T21:41:55.903 回答
0

如果您使用 来创建属性retain,则必须在您的 dealloc 方法中将其设置为 nil。

IE

@interface DMFakeyClass : NSObject

@property (nonatomic, retain) NSString *bogusString;

@end

@implementation DMFakeyClass

-(void)dealloc {
    self.bogusString = nil;
    [super dealloc];
}

@end

这几乎就是您要拥有成功的内存管理策略所要做的所有事情。当您使用此属性时,请始终使用 getter/setter ( self.bogusString = [NSString stringWithString:@"bogus"];) 并确保您已自动释放或释放您分配的任何内容 ( self.bogusString = [[[NSString alloc] initWithString:@"bogus2"] autorelease];)。遵循这种模式,你不应该有任何问题。

于 2011-11-10T20:33:27.217 回答