Alex
Alex

Reputation: 11157

Custom setter for @property?

How can i use a custom setter for the following property after I synthesized it ?

@property (nonatomic,retain) UIButton *but 

Upvotes: 13

Views: 21445

Answers (5)

Simon Tillson
Simon Tillson

Reputation: 3618

I believe this is how the @synthesised setters do it, and it works in all situations, regardless of whether you assign the same object or not:

- (void)setBut: (UIButton*)aButton
{
    id oldObject = but;
    but = [aButton retain];
    [oldObject release];
}

Cannot go wrong, as far as I can see.

Upvotes: 0

Cœur
Cœur

Reputation: 38727

A B+) alternative to deanWombourne solutions:

-(void)setBut:(UIButton *)value {
    [value retain]
    [but release];
    but = value;
}

This solution will prevent issues where value is a sub-object of but.

An A+) alternative to deanWombourne solutions:

-(void)setBut:(UIButton *)value {
    if (but != value) {
        [value retain]
        //insert here but's cancel, invalidate, delegate = nil, ...
        [but release];
        but = value;
    }
}

This solution will prevent issues where value is a sub-object of but. And it will allow you to add a cancel for an NSURLConnection, an invalidate an NSTimer or NSPort, a nil for a delegate, ...

Upvotes: 1

deanWombourne
deanWombourne

Reputation: 38475

@Sascha is almost right but his code has a tiny bug in it ;)

It would look like either :

A)

-(void)setBut:(UIButton *)value {
    if (but != value) {
        [but release];
        but = [value retain];
    }
}

or B)

-(void)setBut:(UIButton *)value {
    [but autorelease];
    but = [value retain];
}

(A) is (very) slightly more efficient, (B) is more readable.


Why do we need the if statement in option (A) instead of just the release & retain in @Sascha's answer?

What happens if you pass in the same object twice?

i.e.

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

If we didn't check that but wasn't a different object, the first thing we would do in our setter is release it. We would then try to retain an object that doesn't exist anymore, causing a crash.

NB We don't need the if statement in option (B) because autorelease won't immediately release the button so we have time to retain it again without it being dealloc'd.

Upvotes: 23

andreamazz
andreamazz

Reputation: 4286

@property (getter=yourGetter,setter=yourSetter:) UIButton *but;

Upvotes: 23

Sascha
Sascha

Reputation: 5973

Implement

- (void)setBut:(UIButton *)aButton;

It should probably look something like

- (void)setBut:(UIButton *)aButton {
    [but release];
    but = [aButton retain];
    // whatever
}

Upvotes: 0

Related Questions