【发布时间】:2011-07-27 10:52:28
【问题描述】:
合成后如何为以下属性使用自定义设置器?
@property (nonatomic,retain) UIButton *but
【问题讨论】:
标签: iphone objective-c ios
合成后如何为以下属性使用自定义设置器?
@property (nonatomic,retain) UIButton *but
【问题讨论】:
标签: iphone objective-c ios
@property (getter=yourGetter,setter=yourSetter:) UIButton *but;
【讨论】:
@Sascha 几乎是对的,但他的代码中有一个小错误 ;)
看起来像:
一)
-(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 的答案中的 release & retain?
如果两次传入同一个对象会怎样?
即
// 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 一个不再存在的对象,从而导致崩溃。
NB 我们不需要选项 (B) 中的 if 语句,因为 autorelease 不会立即释放按钮,因此我们有时间再次保留它而不会将其释放。
【讨论】:
deanWombourne 解决方案的 A B+) 替代方案:
-(void)setBut:(UIButton *)value {
[value retain]
[but release];
but = value;
}
此解决方案将防止 value 是 but 的子对象的问题。
deanWombourne 解决方案的 A+) 替代方案:
-(void)setBut:(UIButton *)value {
if (but != value) {
[value retain]
//insert here but's cancel, invalidate, delegate = nil, ...
[but release];
but = value;
}
}
此解决方案将防止 value 是 but 的子对象的问题。
它允许您为 NSURLConnection 添加 cancel,为 NSTimer 或 NSPort 添加 invalidate,为委托添加 nil,...
【讨论】:
实施
- (void)setBut:(UIButton *)aButton;
它应该看起来像
- (void)setBut:(UIButton *)aButton {
[but release];
but = [aButton retain];
// whatever
}
【讨论】:
我相信@synthesised setter 就是这样做的,它适用于所有情况,无论您是否分配相同的对象:
- (void)setBut: (UIButton*)aButton
{
id oldObject = but;
but = [aButton retain];
[oldObject release];
}
据我所知,不会出错。
【讨论】: