0

I want to invoke a delegate in class method.

The example below obviously does not work, since the delegate is an instance variable that is accessed within a class method. (Error: instance variable 'delegate' accessed in class method)

Is there an alertnative?

My header file:

//  MyClass.h

#import <Foundation/Foundation.h>

@protocol MyDelegate <NSObject>

-(void)update;

@end

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

+(void)methodThatInvokesDelegate;
@end

My implementation file:

//  MyClass.m
#import "MyClass.h"

 @implementation MyClass
 @synthesize delegate;

+(void)methodThatInvokesDelegate{
[delegate update];
 }

 @end
5
  • 3
    you're missing the "@" in front of protocol. what exactly is the problem you're seeing? Commented May 29, 2013 at 11:34
  • @MikeM the above was just an example. Not code that I am actually using. But just to illustrate the problem. I edited my post and added the '@'. The error i': "instance variable 'delegate' accessed in class method Commented May 29, 2013 at 11:38
  • Why do you want to do this? Maybe you're better off using a singleton pattern? Commented May 29, 2013 at 11:39
  • if you want to send a simple "update" to a class, it's maybe enought to use the NSNotificationCenter stackoverflow.com/questions/16409448/… . Else I would recommand to set the methode non-static or use a singleton like @Marcel said Commented May 29, 2013 at 11:49
  • I want to an event to be triggered within a class method. This event is then subscribed to by another class. Commented May 29, 2013 at 11:53

3 Answers 3

3

Three obvious options:

  • Singleton
  • Static variable (i.e., class variable) pointing to the delegate
  • Use NSNotification's rather than delegates

Since a singleton (and a static variable) can't keep track of the lifecycle of delegates, I think option three would be the cleanest.

Sign up to request clarification or add additional context in comments.

9 Comments

I would not take option 3, because notifications are "untargeted", while delegating is "targeted". With targeted I want to say, that delegating points to a specific object.
@AminNegm-Awad I take your point but we're trying to do something a bit odd here so there's bound to be some breakage. I would consider notifications to be the lesser of evils in this case.
This is a subject of taste for sure. But I think, that a static variable is nothing evil. And with notifications, for example, you will never have a return value.
Prior to zeroing weak references, a static delegate would be a crash waiting to happen. Static variables in general are fine but I think delegates are a special case -- because they're dependent on but not in control of another object -- even though, technically, they're just a variable like any other. Also, notifications have the user dictionary, so can pass values back.
How to pass a value back? And whose value? You can have a mass of notification observers.
|
0

I want to know the context, which let you run in that situation. ;-) Anyway:

First: Delegates are set for a specific instance object. Because of this, you can have different delegates for different instances of the same (delegating) class.

Second: A class method runs inside a class object of that class. This is an object that is different from every instance object of that class. So there is nothing that can be called "the delegate". You can have 100s of delegates.

Third: Your class object needs a delegate at its own. So you have to add a property delegate to the class object and then use this. (Yes, it is possible to have properties an a class object. I did not write declared property.) If you need further information on how to do this, just comment it. I will add code.

Comments

0

I'm not sure if this will help you, but I have a similar situation where I have a class method used for data loads. In this case, the class instantiates itself (so that the caller doesn't need to) until it is done. (this code was edited somewhat to make it work here)

header file:

    @protocol DataLoaderDelegate2 <NSObject>
    - (void) dataLoaderSuccess:(NSData *)data loader:(id)theloader;
    - (void) dataLoaderFailed:(NSString *)error loader:(id)theloader;
    @end

    @interface DataLoader2 : NSObject {
            NSURLConnection *conn;
            NSMutableData   *receivedData;
            NSFileHandle    *fileHandle;
            id <DataLoaderDelegate2>    delegate;
    }
    @property (nonatomic, assign) id<DataLoaderDelegate2>delegate;

Call to start the process - the call to initWithRequest passes "self" along.

    + (DataLoader2 *)loadWithURLRequest:(NSURLRequest *)req delegate:(id)_delegate
    {
        DataLoader2 *dl = [[DataLoader2 alloc] init];
        [dl setDelegate:_delegate];
        conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
        return dl;
    }

When the data is done loading, it cleans up with something like

    - (void)connectionDidFinishLoading:(NSURLConnection *)connection
    {

            if ([delegate respondsToSelector:@selector(dataLoaderSuccess:loader:)])
                    [delegate dataLoaderSuccess:(fileHandle)?(id)fileHandle:(id)receivedData loader:self];
            [self autorelease];
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.