雖然TableView的重用機(jī)制很好用,但是....總有一些很尷尬的業(yè)務(wù)場景…比如定時(shí)器的復(fù)用…假如在Cell中定義一個(gè)定時(shí)器簡直重用起來就是爆炸...寫之前我也翻閱了一些簡書相關(guān)的文章,但是...實(shí)現(xiàn)起來都太過繁瑣和復(fù)雜了,有使用通知的(這黑科技)還有用數(shù)組把秒數(shù)裝起來的(坑爹???)….簡直不堪入目...所以我決定自己動手豐衣足食,下面開搞吧
思路現(xiàn)實(shí)##
_面向?qū)ο箝_發(fā),既然每一個(gè)秒殺的數(shù)據(jù)都是一個(gè)對象,只要我讓每一個(gè)對象都管理自己的定時(shí)器不就行了?何必又通知又?jǐn)?shù)組的....同時(shí)重用機(jī)制每次都是按照indexPath來取自身的Model更加不用糾結(jié)定時(shí)器重用的問題..好吧,應(yīng)該這樣寫,問題都能迎刃而解吧??....先試試再說.. _
-
首先是通過網(wǎng)絡(luò)數(shù)據(jù)轉(zhuǎn)化為Model...
'' // SeckillListModel.h
'' //
'' // Created by HuaZao on 16/9/13.
'' // Copyright ? 2016年 HuaZaoGYJ. All rights reserved.
'' //
''
'' #import <Foundation/Foundation.h>
''
'' typedef NS_OPTIONS(NSUInteger,SeckillState) {
'' //未開始
'' SeckillUnStart = 0,
'' //進(jìn)行中
'' SeckillStarting,
'' //已經(jīng)結(jié)束
'' SeckillOver,
'' };
''
'' @interface SeckillListModel : NSObject
''
'' @property (strong,nonatomic) dispatch_source_t timer;
''
'' /** 圖片 */
'' @property (nonatomic, copy) NSString* logoImageList;
''
'' /** 產(chǎn)品唯一ID */
'' @property (nonatomic, copy) NSString* product_mark_id;
''
'' /** 商品ID */
'' @property (nonatomic, assign) NSInteger Id;
''
'' /** 秒殺時(shí)間 */
'' @property (nonatomic, copy) NSString* seckill_time;
''
'' /** 秒殺保持時(shí)間 */
'' @property (nonatomic, assign) NSInteger keep_time;
''
'' /** 已經(jīng)等待了多長時(shí)間 */
'' @property (nonatomic, assign) NSInteger waitTime;
''
'' /** 秒殺已經(jīng)過去的時(shí)間 */
'' @property (nonatomic, assign) NSInteger pass_time;
''
'' /** 服務(wù)器離開始秒殺或者結(jié)束秒殺的時(shí)間差 */
'' @property (nonatomic, assign) NSInteger diffTime;
''
'' /** 名字 */
'' @property (nonatomic, copy) NSString* name;
''
'' /** 狀態(tài) */
'' @property (nonatomic, assign) SeckillState state;
''
'' /** 價(jià)錢 */
'' @property (nonatomic, assign) CGFloat price;
''
'' @end
''
Model中的** timer**字段就是負(fù)責(zé)這個(gè)秒殺產(chǎn)品的定時(shí)器,這個(gè)很重要整個(gè)實(shí)現(xiàn)的核心!
-
接下來就是我們擼一個(gè)Cell出來
''//
'' // seckillingCollectionViewCell.m
'' //
'' // Created by HuaZao on 16/9/12.
'' // Copyright ? 2016年 HuaZaoGYJ. All rights reserved.
'' //
''
'' #import "seckillingCollectionViewCell.h"
''
'' @interface seckillingCollectionViewCell()
''
''
'' @end
''
'' @implementation seckillingCollectionViewCell
''
''
'' -(void)loadCellDataWithProductInfoModel:(SeckillListModel *)model{
'' self.goodStr.text = model.name;
'' [self.goodImageView sd_setImageWithURL:[NSURL URLWithString:model.logoImageList] placeholderImage:[UIImage imageNamed:@"ty_tpjzsb_img_nor"]];
'' switch (model.state) {
'' case SeckillUnStart:
'' self.seckillWaitView.hidden = NO;
'' self.seckillOverView.hidden = YES;
'' self.seckillStartView.hidden = YES;
'' self.seckillWaitTime.text = model.seckill_time;
'' [self startSeckillWithModel:model];
'' break;
'' case SeckillStarting:
'' self.seckillWaitView.hidden = YES;
'' self.seckillOverView.hidden = YES;
'' self.seckillStartView.hidden = NO;
'' //開始倒計(jì)時(shí)
'' [self starTimeCountWithModel:model];
'' break;
'' case SeckillOver:
'' self.seckillWaitView.hidden = YES;
'' self.seckillOverView.hidden = NO;
'' self.seckillStartView.hidden = YES;
'' break;
'' default:
'' break;
'' }
'' }
''
''
'' /*開始秒殺*/
'' -(void)startSeckillWithModel:(SeckillListModel *)model{
'' //應(yīng)該去秒殺了
'' if (model.diffTime == 0) {
'' [self starTimeCountWithModel:model];
'' return;
'' }
''
'' //取真正的時(shí)間差
'' __block NSInteger countDiffTime = model.diffTime - model.pass_time;
''
''
'' if (model.timer == nil){
'' dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
'' model.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
'' dispatch_source_set_timer(model.timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒執(zhí)行
'' //啟動定時(shí)器
'' dispatch_resume(model.timer);
'' }
''
'' dispatch_source_set_event_handler(model.timer, ^{
'' countDiffTime --;
'' NSLog(@"商品秒殺倒計(jì)時(shí)-----%d---%@--",countDiffTime,model.timer);
'' if (countDiffTime == 0) {
'' //關(guān)閉這個(gè)定時(shí)器
'' dispatch_source_cancel(model.timer);
'' model.timer = nil;
'' model.pass_time = 0;
'' model.diffTime = 0;
'' model.state = SeckillStarting;
'' [self starTimeCountWithModel:model];
'' dispatch_async(dispatch_get_main_queue(), ^{
'' self.seckillWaitView.hidden = YES;
'' self.seckillOverView.hidden = YES;
'' self.seckillStartView.hidden = NO;
'' });
'' }
'' });
''
'' }
''
''
'' /*已經(jīng)在秒殺了*/
'' -(void)starTimeCountWithModel:(SeckillListModel *)model{
''
'' //已經(jīng)秒完了
'' if (model.pass_time >= model.keep_time || model.diffTime == model.keep_time){
'' self.seckillWaitView.hidden = YES;
'' self.seckillOverView.hidden = NO;
'' self.seckillStartView.hidden = YES;
'' return;
'' }
''
'' //取真正的時(shí)間差
'' NSInteger deffTime = model.keep_time - model.diffTime - model.pass_time;
''
'' //轉(zhuǎn)分鐘
'' __block NSInteger seckillHour = (deffTime/3600);
'' __block NSInteger seckillMinute = (deffTime/60) % 60;
'' __block NSInteger seckillSecond = deffTime % 60;
''
'' if (model.timer == nil) {
'' dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
'' model.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
'' dispatch_source_set_timer(model.timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒執(zhí)行
'' //啟動定時(shí)器
'' dispatch_resume(model.timer);
'' }
''
'' dispatch_source_set_event_handler(model.timer, ^{
'' seckillSecond --;
'' if (seckillSecond == 0) {
'' if (seckillMinute == 0) {
'' seckillMinute = 0;
''
'' }else{
'' seckillMinute --;
'' seckillSecond = 60;
'' }
'' }
''
'' if (seckillMinute == 0) {
'' if (seckillHour == 0) {
'' seckillHour = 0;
'' }else{
'' seckillHour --;
'' seckillMinute = 60;
'' }
'' }
''
'' NSLog(@"-----%d---%@--",model.pass_time,model.timer);
'' if (seckillHour == 0 && seckillMinute ==0 && seckillSecond == 0) {
'' //關(guān)閉這個(gè)定時(shí)器
'' dispatch_source_cancel(model.timer);
'' model.timer = nil;
'' model.pass_time = 0;
'' dispatch_async(dispatch_get_main_queue(), ^{
'' self.seckillWaitView.hidden = YES;
'' self.seckillOverView.hidden = NO;
'' self.seckillStartView.hidden = YES;
'' });
'' }
'' dispatch_async(dispatch_get_main_queue(), ^{
'' self.seckillTime.text = [NSString stringWithFormat:@"%02d:%02d:%02d",(int)seckillHour,(int)seckillMinute,(int)seckillSecond];
'' });
'' });
''
'' }
'' '' @end
''
''
**上面的代碼比較多,其實(shí)核心代碼就幾句**
'' if (model.timer == nil){
'' '' dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
'' '' model.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
'' '' dispatch_source_set_timer(model.timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0);
'' '' dispatch_resume(model.timer);
'' '' }
'' '' dispatch_source_set_event_handler(model.timer, ^{
'' //做你要處理的事情
'' });
我們只保證每一個(gè)Model的定時(shí)器只存在一個(gè)Cell重用的時(shí)候我們就照樣拿出來執(zhí)行dispatch_source_set_event_handler這個(gè)函數(shù)就沒問題了..這樣我們上面的需求已經(jīng)差不多實(shí)現(xiàn)了..不過總覺得差了一點(diǎn)什么.....總有點(diǎn)不對勁....如果這個(gè)Model定時(shí)器沒初始化到豈不是坑爹????這樣會造成巨大誤差....下面把這個(gè)問題解決了吧...那我只需要…在拿到數(shù)據(jù)的時(shí)候計(jì)時(shí)已經(jīng)過去的時(shí)間不就可以了嗎???
-
解決Cell沒有初始化定時(shí)器造成的問題
在控制器或者View中定義一個(gè)定時(shí)器,用來計(jì)時(shí)已經(jīng)過去了多少時(shí)間
''@implementation seckillingView
''
'' /*開始倒計(jì)時(shí)多余的時(shí)間*/
'' -(void)countPassTime{
'' dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
'' _passTime = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
'' dispatch_source_set_timer(_passTime,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒執(zhí)行
'' dispatch_source_set_event_handler(_passTime, ^{
'' for (SeckillListModel *model in self.viewModel.seckillDataSource) {
'' model.pass_time ++;
'' }
'' });
'' //啟動定時(shí)器
'' dispatch_resume(_passTime);
'' }
'' @end
在Model中定義一個(gè)PassTime用來計(jì)算過去的多少時(shí)間,具體邏輯可以看前面Cell的實(shí)現(xiàn),我們只需要把服務(wù)器時(shí)間減去passtime這樣就可以解決剛剛的問題了,運(yùn)行了一下基本實(shí)現(xiàn)需求了....收工0.0
-
View源碼
''//
'' // seckillingView.m
'' //
'' // Created by HuaZao on 16/9/12.
'' // Copyright ? 2016年 HuaZaoGYJ. All rights reserved.
'' //
'' #import "seckillingCollectionViewCell.h"
'' #import "seckillingView.h"
'' #import "TTDKillGoodInfoViewController.h"
'' #import "indexViewController.h"
'' @interface seckillingView()<UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>
''
'' @property (strong,nonatomic) dispatch_source_t passTime;
''
'' @end
''
'' @implementation seckillingView
''
'' /*開始倒計(jì)時(shí)多余的時(shí)間*/
'' -(void)countPassTime{
'' dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
'' _passTime = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
'' dispatch_source_set_timer(_passTime,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒執(zhí)行
'' dispatch_source_set_event_handler(_passTime, ^{
'' for (SeckillListModel *model in self.viewModel.seckillDataSource) {
'' model.pass_time ++;
'' }
'' });
'' //啟動定時(shí)器
'' dispatch_resume(_passTime);
'' }
''
'' -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
'' return self.viewModel.seckillDataSource.count;
'' }
''
'' -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
'' seckillingCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"seckillCell" forIndexPath:indexPath];
'' [cell loadCellDataWithProductInfoModel:self.viewModel.seckillDataSource[indexPath.row]];
'' return cell;
'' }
''
''
'' -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
'' TTDKillGoodInfoViewController *killVc = [[TTDKillGoodInfoViewController alloc] init];
'' killVc.seckModel = self.viewModel.seckillDataSource[indexPath.row];
'' killVc.goodId = self.viewModel.seckillDataSource[indexPath.row].product_mark_id;
'' [self.viewModel.indexVc.navigationController pushViewController:killVc animated:YES];
'' }
''
''
'' @end