Brett
Brett

Reputation: 12007

iPhone SDK - Avoid casting the class of a delegate

I have an iPhone app in which I have a method in ClassB called:

-(void)login:(NSString *)url withDelegate:(id)delegate { }

this method is called from ClassA. I pass in the delegate parameter in order to pass a callback to ClassA when this method is finished:

if(delegate && [delegate respondsToSelector:@selector(parseLogin:)]) {
   [delegate parseLogin:loginInfoDictionary];
}

However, I get a warning stating: -Instance method: parseLogin: not found

This is not surprising because I never cast the parameter delegate as any specific class. However, to keep this method as abstract as possible, I'd like to keep the datatype of delegate as id.

Is this possible????

I'm running iOS 5.1 (if it matters). I'd like to get rid of the warning if possible.

Many thanks! Brett

Upvotes: 0

Views: 349

Answers (3)

danh
danh

Reputation: 62676

If different classes want to be delegates, declare an @protocol in ClassB.h and have the calling classes adopt that protocol @interface ClassA : UIViewController <ClassBDelegate>.

A little less formally and quicker: if you know that delegate will always be an instance of ClassA? ClassA as the delegate type instead of id.

Even quicker, to just avoid the compiler warning is to leave your code as is, except invoke like this:

if(delegate && [delegate respondsToSelector:@selector(parseLogin:)]) {
   [delegate performSelector:@selector(parseLogin:) withObject:loginInfoDictionary afterDelay:0.0];
}

Upvotes: 1

Jonathan Naguin
Jonathan Naguin

Reputation: 14796

Can't you use a protocol? A protocol like this:

@protocol LoginDelegate <NSObject>

@optional
- (void) parseLogin: (NSDictionary*) dict;

@end

So, in your classA you will use id<LoginDelegate>.

Upvotes: 1

Joseph DeCarlo
Joseph DeCarlo

Reputation: 3278

A common way to handle this is create a protocol and have ClassA implement the protocol.

@protocol ProtocolName
- (void) parseLogin:(NSDictionary*)dictionary;
@end

Then implement the protocol in ClassA

@interface ClassA : NSObject<ProtocolName>

Then change your method to look like:

-(void)login:(NSString *)url withDelegate:(id<ProtocolName>)delegate { }

This will get rid of the warning and still be extensible.

Upvotes: 4

Related Questions