我已将以下变量声明为实例变量并在我的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];
}
啊啊我有autorelease ....但是这并没有解决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
进一步编辑
答案 0 :(得分:5)
如果您定义@property
,那么通常在您访问班级中的ivar时,您可以使用getter / setter,无论是点符号还是标准方法调用。
点符号
id localyMyVar = self.myVar;
self.myVar = @"A string";
标准方法调用
id localMyVar = [self myVar];
[self setMyVar:@"A string"];
如果您始终明确使用这些getter和setter,那么除了dealloc
或重写的setMyVar:
方法之外,您几乎不需要在代码中的任何位置调用release。这样做可以在有限的地方进行内存管理。如果你开始释放并保留自己,那么当你刚开始时,事情会有点复杂。
<强>更新强>
@bbum为您提供答案,但我认为您也可以从编码中更加一致而受益。
例如,在违规行之前,您不使用setter直接分配给ivar。要一致并使用你花时间合成的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 :(得分: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
)
答案 2 :(得分:0)
如果使用retain
创建属性,则必须在dealloc方法中将其设置为nil。
即
@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];
)。遵循这种模式,你不应该有任何问题。