Obj-C, потенциальная утечка объекта, размещенного на линии, предупреждение? - PullRequest
0 голосов
/ 11 ноября 2011

Я объявил следующую переменную в качестве переменной экземпляра и использую ее в своем файле 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

ДОПОЛНИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ enter image description here

Ответы [ 3 ]

5 голосов
/ 11 ноября 2011

Если вы определяете @property, то, как правило, каждый раз, когда вы получаете доступ к ивару в вашем классе, вы используете метод получения / установки, будь то точечная запись или стандартный вызов метода.

Точечная запись

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

Стандартный вызов метода

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

Если вы всегда явно используете эти методы получения и установки, тогда вам почти не нужно вызывать release где-либо в вашем кодекроме dealloc или переопределенного setMyVar: метода.Это позволяет управлять памятью в ограниченных местах.Если вы начнете отпускать и удерживать себя, то все может быть немного сложнее, когда вы только начинаете.

ОБНОВЛЕНИЕ

@ bbum даст вам ответ, но я думаю, вы быВы также можете быть более последовательными в своем кодировании.

Например, перед ошибочной строкой, которую вы назначаете непосредственно ивару без использования установщика.Будьте последовательны и используйте 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;
1 голос
/ 11 ноября 2011
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)

0 голосов
/ 11 ноября 2011

Если вы создаете свойство с retain, вы должны установить его равным nil в вашем методе dealloc.

т.е.

@interface DMFakeyClass : NSObject

@property (nonatomic, retain) NSString *bogusString;

@end

@implementation DMFakeyClass

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

@end

Это почти все, что вам нужно сделать для успешной стратегии управления памятью. Когда вы используете это свойство, всегда используйте метод получения / установки (self.bogusString = [NSString stringWithString:@"bogus"];) и убедитесь, что вы автоматически освободили или освободили все, что вы выделяете (self.bogusString = [[[NSString alloc] initWithString:@"bogus2"] autorelease];). Следуйте этой схеме, и у вас не должно быть проблем.

...