Midhun MP
Midhun MP

Reputation: 107121

Custom delegate issue

I'm working with a custom delegate and protocol functionality.

I implemented my class like follows:

@protocol MyDelegate <NSObject>

@required
- (void)update;

@end

@interface MyHandlerClass : NSObject
{
    id <MyDelegate>delegate;
}
@property (nonatomic, weak) id <MyDelegate>delegate;

@end

My implementation class looks like:

@implementation MyHandlerClass
@synthesize delegate = _delegate;
- (void)updateRequired: (id)sender
{
    if(delegate)
    {
        [delegate update];
    }
}
@end

And from another class I'm setting it like:

[sharedManager setDelegate:self];

But when the updateRequired is triggered it is showing as nil.

Then I added a setter method like:

- (void)setDelegate:(id<MyDelegate>)aDelegate
{
   delegate = aDelegate;
}

Everything works fine !!!

Then I changed the updateRequired method (without custom setter) like:

- (void)updateRequired: (id)sender
    {
        if(_delegate)
        {
            [_delegate update];
        }
    }

It is also working fine !!!

I couldn't find why it is not worked for the first case and why it is worked for the other two cases ?

Please help me to find the issue, Thanks in advance

Upvotes: 1

Views: 421

Answers (3)

foundry
foundry

Reputation: 31745

You have inadvertently declared one ivar called delegate

  id <MyDelegate>delegate;

and another ivar called _delegate

  @synthesize delegate = _delegate;

Some suggestions...

  • don't declare the iVar separately from your @property declaration

  • don't @synthesize, since XCode 4.4 you don't have to. The compiler will autosynthesize and autocreate an iVar with leading underscore

  • always refer to you ivar via it's property, inside and outside of your class. Only exceptions are in init, dealloc and inside custom setters and getters.

So this is how your code should look

    @protocol MyDelegate <NSObject>

    @required
    - (void)update;
    @end

    @interface MyHandlerClass : NSObject
    @property (nonatomic, weak) id <MyDelegate>delegate;
    @end

    @implementation MyHandlerClass

    - (void)updateRequired: (id)sender
    {
        if(self.delegate)
        {
            [self.delegate update];
        }
    }
    @end

Upvotes: 2

Rowan Freeman
Rowan Freeman

Reputation: 16348

When you use

if(delegate)

You are pointing to the instance variable "delegate".

However, when you use

[sharedManager setDelegate:self]

This is setting the instance variable "_delegate" to "self".

Try this:

if (self.delegate) {
    [self.delegate update];
}

Upvotes: 3

Dhruv Goel
Dhruv Goel

Reputation: 2765

To access your delegate property in the updateRequired method, you can do it by either using the private variable _delegate or by using self.delegate. Because when you synthesize using delegate = _delegate, setters and getters are automatically created.

This line tells the compiler to create a setter and getter for delegate, and that they should use the ivar called _delegate. Without the = _delegate part, the compiler would assume that the property and ivar have the same name.

Upvotes: 2

Related Questions