@property的自定义设置器?

时间:2011-07-27 10:52:28

标签: iphone objective-c ios

合成后,如何为自定义setter使用以下属性?

@property (nonatomic,retain) UIButton *but 

5 个答案:

答案 0 :(得分:23)

@Sascha几乎是正确的,但他的代码中有一个小错误;)

它看起来像是:

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];
}

就我所见,不能出错。