如何创建我自己的委托(在目标c中用户定义的委托)

时间:2011-04-14 09:07:42

标签: iphone objective-c

您好 我是iPhone的新手,任何人都可以让我知道。如果要创建一个委托(用户定义),我已对此进行了研究,但未能找到任何满意的答案,任何帮助都将受到高度赞赏 谢谢

2 个答案:

答案 0 :(得分:19)

首先定义一个声明像这样的委托 -

@protocol IconDownloaderDelegate;

然后创建一个像这样的委托对象 -

@interface IconDownloader : NSObject
{
    NSIndexPath *indexPathInTableView;
    id <IconDownloaderDelegate> delegate;
    NSMutableData *activeDownload;
    NSURLConnection *imageConnection;
}

为它声明一个属性 -

@property (nonatomic, assign) id <IconDownloaderDelegate> delegate;

定义它 -

@protocol IconDownloaderDelegate 

- (void)appImageDidLoad:(NSIndexPath *)indexPath;

@end

然后你可以调用这个委托的方法 -

[delegate appImageDidLoad:self.indexPathInTableView];

以下是图片下载程序类的完整源代码 -

.h文件 -

@class AppRecord;
@class RootViewController;

@protocol IconDownloaderDelegate;

@interface IconDownloader : NSObject
{
    AppRecord *appRecord;
    NSIndexPath *indexPathInTableView;
    id <IconDownloaderDelegate> delegate;

    NSMutableData *activeDownload;
    NSURLConnection *imageConnection;
}

@property (nonatomic, retain) AppRecord *appRecord;
@property (nonatomic, retain) NSIndexPath *indexPathInTableView;
@property (nonatomic, assign) id <IconDownloaderDelegate> delegate;

@property (nonatomic, retain) NSMutableData *activeDownload;
@property (nonatomic, retain) NSURLConnection *imageConnection;

- (void)startDownload;
- (void)cancelDownload;

@end

@protocol IconDownloaderDelegate 

- (void)appImageDidLoad:(NSIndexPath *)indexPath;

@end

.m文件 -

#import "IconDownloader.h"
#import "MixtapeInfo.h"

#define kAppIconHeight 48
#define TMP NSTemporaryDirectory()

@implementation IconDownloader

@synthesize appRecord;
@synthesize indexPathInTableView;
@synthesize delegate;
@synthesize activeDownload;
@synthesize imageConnection;

#pragma mark

- (void)dealloc
{
    [appRecord release];
    [indexPathInTableView release];

    [activeDownload release];

    [imageConnection cancel];
    [imageConnection release];

    [super dealloc];
}

- (void)startDownload
{
    self.activeDownload = [NSMutableData data];

    // alloc+init and start an NSURLConnection; release on completion/failure
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:
                             [NSURLRequest requestWithURL:
                              [NSURL URLWithString:appRecord.mixtape_image]] delegate:self];
    self.imageConnection = conn;
    [conn release];

}

- (void)cancelDownload
{
    [self.imageConnection cancel];
    self.imageConnection = nil;
    self.activeDownload = nil;
}


#pragma mark -
#pragma mark Download support (NSURLConnectionDelegate)

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [self.activeDownload appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    // Clear the activeDownload property to allow later attempts
    self.activeDownload = nil;

    // Release the connection now that it's finished
    self.imageConnection = nil;
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{   
    // Set appIcon and clear temporary data/image
    UIImage *image = [[UIImage alloc] initWithData:self.activeDownload];
    self.appRecord.mixtape_image_obj = image;

    self.activeDownload = nil;
    [image release];

    // Release the connection now that it's finished
    self.imageConnection = nil;

    // call our delegate and tell it that our icon is ready for display
    [delegate appImageDidLoad:self.indexPathInTableView];
}

@end

以下是我们如何使用它 -

#import "IconDownloader.h"

@interface RootViewController : UITableViewController <UIScrollViewDelegate, IconDownloaderDelegate>
{
    NSArray *entries;   // the main data model for our UITableView
    NSMutableDictionary *imageDownloadsInProgress;  // the set of IconDownloader objects for each app
}
<。>在.m文件中 -

- (void)startIconDownload:(AppRecord *)appRecord forIndexPath:(NSIndexPath *)indexPath
{
    IconDownloader *iconDownloader = [imageDownloadsInProgress objectForKey:indexPath];
    if (iconDownloader == nil) 
    {
        iconDownloader = [[IconDownloader alloc] init];
        iconDownloader.appRecord = appRecord;
        iconDownloader.indexPathInTableView = indexPath;
        iconDownloader.delegate = self;
        [imageDownloadsInProgress setObject:iconDownloader forKey:indexPath];
        [iconDownloader startDownload];
        [iconDownloader release];   
    }
}

这里是委托自动调用 -

// called by our ImageDownloader when an icon is ready to be displayed
- (void)appImageDidLoad:(NSIndexPath *)indexPath
{
    IconDownloader *iconDownloader = [imageDownloadsInProgress objectForKey:indexPath];
    if (iconDownloader != nil)
    {
        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:iconDownloader.indexPathInTableView];

        // Display the newly loaded image
        cell.imageView.image = iconDownloader.appRecord.appIcon;
    }
}

答案 1 :(得分:1)

这是创建自己的委托的基本概念

代理对于手动控制应用程序中视图控制器数组内的传输非常有用。使用代理,您可以很好地管理控制流程。

这是自己代表的一个小例子......

  1. 创建协议类....(仅限.h)
  2. SampleDelegate.h

    #import
    
    
    @protocol SampleDelegate
    @optional
    
    #pragma Home Delegate
    
    -(NSString *)getViewName;
    
    @end
    
    1. 在您要为另一个类委托的类中导入上面的协议类。在我的前任。我正在使用AppDelegate来创建HomeViewController的Object的委托。
    2. 还在Delegate Reference&lt;中添加了DelegateName。 &GT;

      ownDelegateAppDelegate.h

      #import "SampleDelegate.h"
      
      @interface ownDelegateAppDelegate : NSObject <UIApplicationDelegate, SampleDelegate> {
      
      }
      

      ownDelegateAppDelegate.m

      //setDelegate of the HomeViewController's object as
      [homeViewControllerObject setDelegate:self];
      
      //add this delegate method definition
      -(NSString *)getViewName
      {
          return @"Delegate Called";
      }
      

      HomeViewController.h

      #import
      #import "SampleDelegate.h"
      
      @interface HomeViewController : UIViewController {
      
          id<SampleDelegate>delegate;
      }
      
      @property(readwrite , assign) id<SampleDelegate>delegate;
      
      @end
      

      HomeViewController.h

      - (void)viewDidAppear:(BOOL)animated {
      
          [super viewDidAppear:animated];
      
      
          UILabel *lblTitle = [[UILabel alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
          lblTitle.text = [delegate getViewName];
          lblTitle.textAlignment = UITextAlignmentCenter;
          [self.view addSubview:lblTitle];
      }