今天跟大家分享四种常用的传值方式,这四种都非常重要!如果文中有什么错误的地方,还请大家指出,本人一定改正!
[ http://www.weibo.com/3131266221/profile?topnav=1&wvr=6 ]
/*我的需求:在需要下载图片的地方(ViewController)创建一个DownloadImage的对象,然后调用下载的方法,下载完毕后将下载下来的图片返回给ViewController,显示到界面上/
/*第一种:代理传值/
model.h
@protocol DownloadImageDelegate <NSObject>
@required
-(void)downloadImageFinished: (UIImage *)image;
@end
@interface DowndloadImage : NSObject
@property (nonatomic,assign) id<DownloadImageDelegate>delegate;
@end
model.m
-(void)downloadImageWithUrlStr: (NSString *)urlStr
{
/**异步调用全局的子线程,下载图片*/
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
NSURL *url = [NSURL URLWithString:urlStr];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
/**下载图片完成后异步调用主线程*/
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
/**如果_delegate里面有内容,而且[_delegate respondsToSelector:@selector(downloadImageFinished:)]这个方法已经调用,则进入这个if执行语句*/
if (_delegate && [_delegate respondsToSelector:@selector(downloadImageFinished:)]) {
/**线程间的通信*/
[_delegate performSelector:@selector(downloadImageFinished:) withObject:image];
}
});
});
}
ViewController.h
只要遵守这个协议就OK。
ViewController.m
/**1.创建一个DownloadImage的对象*/
DowndloadImage *downloadImage = [[DowndloadImage alloc] init];
/**2.设置代理,让本类来实现方法*/
downloadImage.delegate = self;
/**3.给下载图片类传一个图片*/
[downloadImage downloadImageWithUrlStr:@"http://e.hiphotos.baidu.com/image/pic/item/5fdf8db1cb13495405b54f62544e9258d1094a08.jpg"];
/**4.实现协议方法*/
-(void)downloadImageFinished:(UIImage *)image
{
_iamgeView = [[UIImageView alloc]initWithFrame:self.view.bounds];
_iamgeView.image = image;
[self.view addSubview:_iamgeView];
}
//到这里就传值OK了!
/*第二种:通知传值,这个传值和代理传值差不多,但有本质上的区别/
model.h
@interface DowndloadImage : NSObject
/**通知传值*/
@property (nonatomic, assign) id target;
@property (nonatomic, assign) SEL action;
@end
model.m
-(void)downloadImageWithUrlStr: (NSString *)urlStr
{
/**异步调用全局的子线程,下载图片*/
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
NSURL *url = [NSURL URLWithString:urlStr];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
/**下载图片完成后异步调用主线程*/
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
/**通知传值*/
if (_target &&[_target respondsToSelector:_action]) {
[_target performSelector:_action withObject:image];
}
});
});
}
ViewController.h
这个方法.h里面什么都不用写哦
ViewController.m
/**设置target用通知传值*/
downloadImage.target = self;
downloadImage.action = @selector(downloadImageFinished:);
DowndloadImage *downloadImage = [[DowndloadImage alloc] init];
/**给下载图片类传一个图片*/
[downloadImage downloadImageWithUrlStr:@"http://e.hiphotos.baidu.com/image/pic/item/5fdf8db1cb13495405b54f62544e9258d1094a08.jpg"];
/**实现指定的方法*/
-(void)downloadImageFinished:(UIImage *)image
{
_iamgeView = [[UIImageView alloc]initWithFrame:self.view.bounds];
_iamgeView.image = image;
[self.view addSubview:_iamgeView];
}
通知传值到这就OK了。
/*第三种:block方式的回调,用block进行传值/
model.h
/**1.定义一个block类型,block的名字是DownloadFinishBlock,无返回值*/
typedef void (^DowndloadFinish)(UIImage *image);
@interface DowndloadImage : NSObject
{
DowndloadFinish _block;
}
/**写一个成员变量的set方法*/
-(void)setBlock: (DowndloadFinish)block;
@end
model.m
-(void)downloadImageWithUrlStr: (NSString *)urlStr
{
/**异步调用全局的子线程,下载图片*/
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
NSURL *url = [NSURL URLWithString:urlStr];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
/**下载图片完成后异步调用主线程*/
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
/**4.block 调用属性block,把image作为参数毁掉给ViewController*/
if (_block) {
_block(image);
}
});
});
}
/**写block的set方法*/
-(void)setBlock:(DowndloadFinish)block
{
_block = block;
}
ViewController.h
这个方法.h也不用写任何东西哦
ViewController.m
DowndloadImage *downloadImage = [[DowndloadImage alloc] init];
/**给下载图片类传一个图片*/
[downloadImage downloadImageWithUrlStr:@"http://e.hiphotos.baidu.com/image/pic/item/5fdf8db1cb13495405b54f62544e9258d1094a08.jpg"];
//用setBlock的方式来传一个参数
[downloadImage setBlock:^(UIImage *image) {
_iamgeView = [[UIImageView alloc]initWithFrame:self.view.bounds];
_iamgeView.image = image;
[self.view addSubview:_iamgeView];
}];
/**第四种:
- 列表内容
通知中心传值*/
/*~~~~~~~~~~~~~~~~~通知不同于代理的是,它可以一对多的进行传递/
model.h
define kDownloadFinishNotification @"kDownloadFinishNotification"
model.m
-(void)downloadImageWithUrlStr: (NSString *)urlStr
{
/**异步调用全局的子线程,下载图片*/
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
NSURL *url = [NSURL URLWithString:urlStr];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
/**下载图片完成后异步调用主线程*/
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
/**生成通知中心,传递数据*/
[[NSNotificationCenter defaultCenter] postNotificationName:kDownloadFinishNotification object:image];
});
});
}
ViewController.h
这里也什么都不用写
ViewController.m
/**注册通知中心添加一个观察者,当我post这个kDownloadFinishNotification通知的时候,self将执行selector对应的方法*/
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadImageFinishedNotification:) name:kDownloadFinishNotification object:nil];
/**通知中心传值*/
-(void)downloadImageFinishedNotification: (NSNotification *)noti
{
UIImage *image = noti.object;
_iamgeView = [[UIImageView alloc]initWithFrame:self.view.bounds];
_iamgeView.image = image;
[self.view addSubview:_iamgeView];
}