我很抱歉转发。真正让我烦恼的是,如果属性保留应该在以下情况下释放:
情况1 :(下面的代码)按钮已经在init中分配:然后添加到子视图然后释放它,并且任何机会我在另一个类中设置按钮属性(我没有在dealloc中释放:)它会泄漏吗?登记/>
情况2:按钮已经在init中分配:然后添加到子视图然后释放它,并且任何机会我没有在另一个类中设置任何按钮属性(我没有使用该属性)(我在dealloc中释放它)然后就会崩溃。
那么,如果我想在init中分配按钮,我该怎么办?我也想设置属性?
@interface SomeClass : UIView {
UIButton *_button;
}
@property (nonatomic, retain)UIButton *button;
@implementation SomeClass
@synthesize button = _button;
- (id)init {
_button = [[UIbutton alloc] initWithFrame:CGRectMake(0.0f,0.0f,100.0f,20.0f)];
[[_button titleLabel] setFont:BUTTON_FONT];
[_button setBackgroundImage:[[UIImage imageNamed:@"button_blue.png"] stretchableImageWithLeftCapWidth:20.0f topCapHeight:15.0f] forState:UIControlStateNormal];
[_button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_button setTitleShadowColor:[UIColor blackColor] forState:UIControlStateNormal];
[[_button titleLabel] setShadowOffset:CGSizeMake(0.0f, 1.0f)];
[_button addTarget:self action:@selector(buttonDidTapped:) forControlEvents:UIControlEventTouchUpInside];
[self addSubView:_button];
[_button release];
}
- (void)dealloc {
//[self.button release]; // case 1
[self.button release]; // case 2
[super dealloc];
}
@end
答案 0 :(得分:2)
那么,如果我想在init中分配按钮,我该怎么办?我也想设置属性?
以下是您的代码的外观:
@implementation SomeClass
@synthesize button = _button;
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
UIButton *button = [[UIbutton alloc] initWithFrame:CGRectMake(0.0f,0.0f,100.0f,20.0f)];
// Setup the button here...
[self addSubView:button];
self.button = button;
[button release];
}
return self;
}
- (void)dealloc {
[_button release];
[super dealloc];
}
@end
我所做的改变:
initWithFrame:
是UIView
的指定初始值设定项,因此这是您必须覆盖的init方法_button
iVar有效或无效。无论哪种方式调用该变量的释放都可以。答案 1 :(得分:1)
我不明白“将它用于只读”是什么意思。如声明的那样,该属性对于类本身和外部都是可读写的。但是问题可以合理地回答 - 一旦你的类保留了一些对象,它必须在它被解除分配时释放它。
P.S。我认为您可以安全地删除私有变量的下划线前缀,它没有任何实际意义,并且可以让您编写更多代码。实际上,使用现代运行时,您甚至可以删除实例变量声明:
@interface Foo : NSObject {}
@property(assign) BOOL bar;
@end
@implementation Foo
@synthesize bar;
@end
答案 2 :(得分:1)
好的,第三次尝试:问题是你实际上是通过分配实例变量来设置属性。当您提供以下声明时,属性和实例变量紧密相关...
@synthesize button = _button;
...您说的是_button
实例变量应该用于存储button
属性的值。这意味着您的代码过度发布,因为您在init
(+1)中分配按钮,释放init
( - 1)中的按钮,然后再次在dealloc
中释放( - 再次1)。
如果您尚未研究Cocoa Memory Management Guide,请执行此操作。即使你不打算阅读任何其他文件(这可能是遗憾的),用这个文件做一个例外,它会给你足够的回报。
答案 3 :(得分:0)
当然,你应该释放它,因为你已经使用了retain。
答案 4 :(得分:0)
在-init
方法中,您有一个平衡的retain
/ release
来电。所以你不需要再次发布它。但通过这样做,你牺牲了_button
所持有的价值的可靠性。如果在通道的某个位置按钮被从子视图中移除,则按钮的retainCount可能会达到零并且可以取消分配。然后_button
保持的值是垃圾。因此,您不应在_button
中发布-init
,而应该在-dealloc
中执行此操作。
现在,如果你在其他地方(在这个UIView对象之外)访问该属性,除非你将它保留在那里,否则你不需要再次释放它。
答案 5 :(得分:-2)
尝试将[self.button release];
替换为[self.button removeFromSuperview];