2010-07-16 32 views
0

场景:需要在视图控制器上执行CustomWebview委托。如何在iPhone中使用协议代替代理

请帮我这个代码。而不是使用回调,我需要使用“协议”。可以这样做,否则我们只能在这种情况下使用回调。

在ViewController.m

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    //MyWebView *webView = [[MyWebView alloc] initWithDelegate:self callback:@selector(finishLoading)]; 

    MyWebView *webView= [[MyWebView alloc] initWithFrame:CGRectMake(0,0,320, 460)]; 
    [webView LoadURL:@"http://192.168.5.165/"]; 
    [webView setDelegate:self]; 
    [webView setCallback:@selector(finishLoading)]; 
    [self.view addSubview:webView] ; 
} 

- (void) finishLoading 
{ 
    NSLog(@"Finish"); 
} 

在MyWebView.h

@interface MyWebView : UIView<UIWebViewDelegate> { 
    NSString *strURL; 
} 
@property(nonatomic, retain) NSString *strURL; 
@property (nonatomic, assign) id delegate; 
@property (nonatomic, assign) SEL callback; 

-(void) LoadURL:(NSString*)url; 
@end 

在MyWebView.m

#import "MyWebView.h" 

@implementation MyWebView 
@synthesize strURL,delegate,callback; 
UIWebView *webView; 
-(id) initWithFrame:(CGRect)frame 
{ 
    if(self =[super initWithFrame:frame]) 
    { 
     webView = [[UIWebView alloc] initWithFrame:frame]; 
     webView.delegate = self; 
     [self addSubview:webView]; 

    } 
    return self; 
} 

-(void) LoadURL:(NSString*)url 
{ 
    NSURL *u = [NSURL URLWithString:url]; 
    NSURLRequest *req= [NSURLRequest requestWithURL:u]; 
    [webView loadRequest:req]; 
} 

- (void)webViewDidFinishLoad:(UIWebView *)webView 
{ 
    [delegate performSelector:callback]; 
} 

回答

3

你的问题有点不清楚。协议和代表是两个完全独立的,但相关的东西 - 苹果和桔子。协议定义的方法的列表对象可以或必须响应:

@protocol Document 
+ (id)documentWithContentsOfURL: (NSURL *)aURL; 
- (void)writeToURL: (NSURL *)aURL error: (NSError **)outError; 
@end 

委托是一个对象,通常为自定义类的实例,即交给另一个目的为加工定制或反馈 - 即后一个对象代表工作到委托对象。


您是否问如何将NSObject上的委托类别转换为委托协议? (前者曾经是Apple定义代表义务和能力的模式;后者是更新的方式来做同样的事情)。如果是这样,它通常看起来像这样:

NSObject上的委托类别

@interface NSObject (WidgetDelegate) 
- (void)doSomethingWithWidget: (Widget *)w; 
@end 

@interface Widget : NSObject 
@property (readwrite, assign) id delegate; 
@end 

委托协议

@protocol WidgetDelegate <NSObject> 
- (void)doSomethingWithWidget: (Widget *)w; 
@end 


@interface Widget : NSObject 
@property (readwrite, assign) id <WidgetDelegate> delegate; 
@end 

这就是你想要的?如果不是,你能澄清你想要做什么吗?

+0

我知道上面的代码可具有协议,在这种情况下我不不需要使用CALLBACK。只是不知道如何实施Protocol。您可以请帮助更改代码通过使用协议而不是CALLBACK。 – iPhoneDev 2010-07-16 08:43:47

+0

你的意思是你想让你自己的类有一个委托协议(独立于'UIWebViewDelegate')?如果是这样,请定义协议(如上所示),将您的委托属性的类型从'id'更改为'id ',并使用'[self.delegate performSelector:@selector(theDelegateMethod :) withObject:self]'或'objc_msgSend(self.delegate,@selector(theDelegateMethod :),self)'将消息发送给委托。 (如果协议将该方法定义为可选,请务必检查是否可以先用'[self.delegate respondsToSelector:@selector(theDelegateMethod :)]'调用它!) – 2010-07-16 16:13:55

+0

In MyWebView.h @protocol webProtocol - (void)loadWeb; @end @property(nonatomic,assign)id delegate ;.现在我该如何在“ViewControler.m”中实现这个功能 – iPhoneDev 2010-07-19 10:51:23

0

另请参阅Apple的Communicating with Objects,其中讨论代表,协议和选择器。虽然它在Mac OS X中列出,但大多数(如果不是全部的话)似乎也适用于iOS。

0

在ViewController.m

@interface MyViewController : UIViewController<MyFinishLoadingDelegate> { 
//your own definition 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    //MyWebView *webView = [[MyWebView alloc] initWithDelegate:self callback:@selector(finishLoading)]; 

    MyWebView *webView= [[MyWebView alloc] initWithFrame:CGRectMake(0,0,320, 460)]; 
    [webView LoadURL:@"http://192.168.5.165/"]; 
    [webView setDelegate:self]; 
    [self.view addSubview:webView] ; 
} 

- (void)finishLoading //this is your implementation for MyFinishLoadingDelegate 
{ 
    NSLog(@"Finish"); 
} 

在MyWebView.h

//you declare the protocol here to tell anyone who'd like to act like your delegate that they need to implement "finishLoading" 
@protocol MyFinishLoadingDelegate <NSObject> 
- (void)finishLoading; 
@end 

@interface MyWebView : UIView<UIWebViewDelegate> { 
    NSString *strURL; 
} 
@property(nonatomic, retain) NSString *strURL; 
@property (nonatomic, assign) id<MyFinishLoadingDelegate> delegate; 

-(void) LoadURL:(NSString*)url; 
@end 

在MyWebView.m

- (void)webViewDidFinishLoad:(UIWebView *)webView 
{ 
    [delegate finishLoading]; 
}