如何创建自己的代理(Objective-C中的用户定义代理)
这是创建自己的委托的基本概念。
委托非常有用,可以手动控制应用程序中视图控制器数组之间的传递。使用委托可以很好地管理控制流。
这里是自己委托的一个小例子....
- 创建一个协议类....(仅.h文件)
SampleDelegate.h
#import @protocol SampleDelegate @optional #pragma Home Delegate -(NSString *)getViewName; @end
- 在想要将另一个类的委托的类中导入上述协议类。在我的示例中,我使用AppDelegate将其委托为HomeViewController的对象。
还要在Delegate Reference中添加上述DelegateName。
ownDelegateAppDelegate.h
#import "SampleDelegate.h" @interface ownDelegateAppDelegate : NSObject{ }
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 { iddelegate; } @property(readwrite , assign) id 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]; }
首先定义一个代理,如下所示 -
@protocol IconDownloaderDelegate;
然后创建一个代理对象,如下所示 -
@interface IconDownloader : NSObject { NSIndexPath *indexPathInTableView; iddelegate; NSMutableData *activeDownload; NSURLConnection *imageConnection; }
为其声明一个属性 -
@property (nonatomic, assign) iddelegate;
定义它 -
@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; iddelegate; NSMutableData *activeDownload; NSURLConnection *imageConnection; } @property (nonatomic, retain) AppRecord *appRecord; @property (nonatomic, retain) NSIndexPath *indexPathInTableView; @property (nonatomic, assign) id 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{ 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; } }