Question

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

Was it helpful?

Solution 2

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

OTHER TIPS

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top