合成后,如何为自定义setter使用以下属性?
@property (nonatomic,retain) UIButton *but
答案 0 :(得分:23)
它看起来像是:
A)
-(void)setBut:(UIButton *)value {
if (but != value) {
[but release];
but = [value retain];
}
}
或B)
-(void)setBut:(UIButton *)value {
[but autorelease];
but = [value retain];
}
(A)(非常)效率稍高,(B)更具可读性。
为什么我们需要选项(A)中的if语句而不仅仅是发布&留在@Sascha的回答中?
如果两次传入同一个对象会怎样?
即
// We set our button for the first time
UIButton *test = [UIButton alloc] init];
[self setBut:test];
[test release];
// Much later in the code, we set the button again
[self setBut:test];
如果我们没有检查but
不是一个不同的对象,那么我们在setter中做的第一件事就是release
它。然后我们会尝试retain
一个不再存在的对象,导致崩溃。
注意我们不需要选项(B)中的if语句,因为自动释放不会立即释放按钮,所以我们有时间再次保留它而不会被释放。
答案 1 :(得分:22)
@property (getter=yourGetter,setter=yourSetter:) UIButton *but;
答案 2 :(得分:1)
A + B替代deanWombourne解决方案:
-(void)setBut:(UIButton *)value {
[value retain]
[but release];
but = value;
}
此解决方案可以防止 value 是但的子对象的问题。
替代deanWombourne解决方案的A +):
-(void)setBut:(UIButton *)value {
if (but != value) {
[value retain]
//insert here but's cancel, invalidate, delegate = nil, ...
[but release];
but = value;
}
}
此解决方案可以防止 value 是但的子对象的问题。
它允许您为NSURLConnection,cancel
和NSTimer或NSPort添加invalidate
,为代表添加nil,...
答案 3 :(得分:0)
实施
- (void)setBut:(UIButton *)aButton;
应该看起来像
- (void)setBut:(UIButton *)aButton {
[but release];
but = [aButton retain];
// whatever
}
答案 4 :(得分:0)
我相信这就是@synthesised的制定者如何做到这一点,它适用于所有情况,无论你是否分配同一个对象:
- (void)setBut: (UIButton*)aButton
{
id oldObject = but;
but = [aButton retain];
[oldObject release];
}
就我所见,不能出错。