简体   繁体   中英

using a delegate in a class method

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

Three obvious options:

  • Singleton
  • Static variable (ie, 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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM