iOS 開發(fā)中為controller 瘦身

在以往的開發(fā)中煮纵,使用MVC架構(gòu)模式的時(shí)候還是居多的,MVC方便的是職責(zé)比較明確偏螺,View負(fù)責(zé)界面的展示行疏,Model存儲(chǔ)數(shù)據(jù)模型,controller負(fù)責(zé)業(yè)務(wù)邏輯套像,原先使用的時(shí)候酿联,Model 使用的是瘦Model的形式,只存儲(chǔ)數(shù)據(jù)模型凉夯,不處理業(yè)務(wù)邏輯货葬,這就導(dǎo)致一個(gè)問題,就是controller的職責(zé)越來越重劲够,需要處理的東西越來越多震桶,包括頁面的構(gòu)建、網(wǎng)絡(luò)請(qǐng)求的處理征绎、頁面的跳轉(zhuǎn)蹲姐,代理方法、響應(yīng)方法等人柿。這樣的結(jié)果是導(dǎo)致controller越來越厚重柴墩,代碼堆積越來越多,少則幾百行代碼凫岖,多則二三千行代碼江咳,這也會(huì)使代碼的后期維護(hù)變得異常艱難,特別是接手別人的代碼哥放,修改bug定位問題會(huì)花費(fèi)更多的時(shí)間歼指,所以我們盡量要從controller抽離一部分的代碼邏輯爹土,為controller瘦身。

一踩身、將View的代碼移到View層

這一方面相信大多數(shù)人做的比較好胀茵,一個(gè)頁面肯定有許多視圖, 以首頁為例子 包括 banner視圖、點(diǎn)擊跳轉(zhuǎn)視圖挟阻、列表視圖琼娘、推薦視圖、尾部視圖附鸽、對(duì)于每一個(gè)模塊的視圖應(yīng)該進(jìn)行子類化封裝脱拼,

#import "HomebannerView.h"
#import "HomeOperationView.h"
#import "HomeMainListView.h"
#import "HomeSecondKillView.h"
#import "HomeTrailsView.h"

然后在控制器中進(jìn)行add

    [self.view addSubview:self.containerView];
    [self.containerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.bottom.with.offset(0);
    }];

    [self.containerView addSubview:self.bannerView];
    [self.bannerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.right.offset (0);
        make.height.mas_equalTo (143 * KHEIGHT_IPHONE6_SCALE);
    }];
//...后續(xù)View的構(gòu)建添加

二、將網(wǎng)絡(luò)請(qǐng)求移動(dòng)到Model層

新的項(xiàng)目之后 拒炎,除了Model挪拟、View、Controller之外击你,我會(huì)單獨(dú)新建一個(gè)ViewModel類玉组,用于處理部分邏輯,在.h文件中將邏輯的方法暴露給controller調(diào)用丁侄,邏輯處理完將 處理結(jié)果回調(diào)給controller進(jìn)行處理


屏幕快照01.png

在ViewModel中進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)的獲取以及解析或者后續(xù)的邏輯操作

///IntelGeneDetailViewModel.h 文件
//組合產(chǎn)品是否可投資信息
@property (nonatomic, strong) NSError *investDataError;
@property (nonatomic, strong) InGenDetaiInvestInfoModel *investInfoModel;
@property (nonatomic, assign) BOOL isInvestInfoCompleted;

  //請(qǐng)求曲線數(shù)據(jù)
- (void)requestForTrendLineDataWithPortfolioId:(NSString *)portfolioId portfolioType:(NSString *)portfolioType duration:(NSString *)duration;

// 獲得組合產(chǎn)品是否可投資信息
- (void)requestForInvestEnableInfoWithPortfolioId:(NSString *)portfolioId portfolioType:(NSString *)portfolioType content_pk:(NSString *)content_pk;


// IntelGeneDetailViewModel.m 文件
/**
 請(qǐng)求組合詳情頁數(shù)據(jù)
 */
- (void)requestForGenDetailDataWithPortfolioId:(NSString *)portfolioId portfolioType:(NSString *)portfolioType {
    NSMutableDictionary *dataDic = [NSMutableDictionary dictionary];
    [dataDic setObject:portfolioId forKey:@"portfolio_id"];
    [dataDic setObject:portfolioType forKey:@"portfolio_type"];
    [dataDic addEntriesFromDictionary:self.baseParams];
    [dataDic addEntriesFromDictionary:self.userParams];
    [[ATTNetwork shareInstance] getWithURL:APIManager.intelGetPortfolioDetailInfo params:dataDic isLoading:YES success:^(id response) {
        [self handleIntelGenDetailResponse:response];
    } failure:^(NSError *error) {
        self.intelGenDetailError = error;
    }];
}


- (void)handleIntelGenDetailResponse:(id)response {
    response = [Util dictionaryWithJSON:response];
    DebugLog(@"組合詳情頁數(shù)據(jù)=%@",response);
    BOOL isSuccess = [response[@"is_success"] boolValue];
    if (!isSuccess) {
        NSString *errorMessage = response[@"error_msg"];
        [[UIViewController currentViewController] showToast:errorMessage];
        return;
    }
    NSDictionary *dataDic = response[@"data"];
    IntelGenDetailModel *intelGenDetailModel = [IntelGenDetailModel mj_objectWithKeyValues:dataDic];
    self.intelGenDetailModel = intelGenDetailModel;
}

處理完的數(shù)據(jù)結(jié)果可以通過 block 惯雳、或者代理等方式回傳給controller做進(jìn)一步的數(shù)據(jù)處理,筆者習(xí)慣使用RAC的方式 在controller 監(jiān)聽 viewModel中值的變化來進(jìn)行值的回傳鸿摇。


    //頁面數(shù)據(jù)
    [[RACObserve(self.mainViewModel, intelGenDetailError)ignore:nil]subscribeNext:^(NSError *error) {
        @strongify(self);
        DebugLog(@"錯(cuò)誤代碼=%ld, 錯(cuò)誤描述%@", error.code , error.description);
        [self handleNetworkError:error];
    }];
    
    [[RACObserve(self.mainViewModel, intelGenDetailModel)ignore:nil]subscribeNext:^(IntelGenDetailModel *model) {
        @strongify(self);
        self.detailModel = model; 
       [self handleDataAfterCompleted];
    }];

其實(shí)在抽擬的viewModel層不單單可以進(jìn)行網(wǎng)絡(luò)請(qǐng)求石景,還可以進(jìn)行部分邏輯的處理,每個(gè)模塊的高度計(jì)算拙吉,模塊的隱藏與顯示潮孽,跳轉(zhuǎn)的邏輯等等

三、結(jié)構(gòu)復(fù)雜的頁面建議使用child view Controller

如圖的結(jié)構(gòu)頁面


屏幕快照03.png

當(dāng)前控制器可以再細(xì)分好幾個(gè)模塊的情況下筷黔,千萬不要幾個(gè)頁面的邏輯操作寫在一個(gè)controller中往史,如果那樣做,那簡直是噩夢(mèng)佛舱。隨著每個(gè)頁面中邏輯和頁面結(jié)構(gòu)的復(fù)雜性椎例,controller中的代碼會(huì)越來越不可控。所以建議一旦一個(gè)頁面下面有明顯的可以細(xì)分的頁面请祖,最好使用child viewController,簡單的邏輯如下

        [self addChildViewController:currentVC];
        [currentVC didMoveToParentViewController:self];
        currentVC.view.frame = CGRectMake(SCREEN_WIDTH * _initiaIndex, 0, SCREEN_WIDTH, SCREEN_HEIGHT - 49 - 64);
        [self.pageScrollView addSubview:currentVC.view];

總結(jié)

其實(shí)這些是在項(xiàng)目中使用的最基礎(chǔ)的 Controller 瘦身的一些做法订歪,其實(shí)整個(gè)項(xiàng)目中 用的最多的還是 第一條和第二條的總結(jié),因?yàn)樗械目刂破鞫紩?huì)有這樣的操作肆捕,有時(shí)候都會(huì)在Controller中一不小心就會(huì)寫下幾千行的代碼刷晋,其實(shí)代碼規(guī)范應(yīng)該作為自己的代碼習(xí)慣去遵守,寫出可用性、可讀性的代碼是每個(gè)程序員應(yīng)該做到的眼虱,這樣保證自己項(xiàng)目的可維護(hù)性以及后續(xù)的可擴(kuò)展性或舞,即便是別人接手了你的代碼,至少不會(huì)罵人蒙幻,????。胆筒。邮破。其實(shí)需要Controller瘦身的還有很多,以后項(xiàng)目中會(huì)繼續(xù)總結(jié)仆救。抒和。。彤蔽。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末摧莽,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子顿痪,更是在濱河造成了極大的恐慌镊辕,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚁袭,死亡現(xiàn)場(chǎng)離奇詭異征懈,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)揩悄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門卖哎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人删性,你說我怎么就攤上這事亏娜。” “怎么了蹬挺?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵维贺,是天一觀的道長。 經(jīng)常有香客問我汗侵,道長幸缕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任晰韵,我火速辦了婚禮发乔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘雪猪。我一直安慰自己栏尚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布只恨。 她就那樣靜靜地躺著译仗,像睡著了一般抬虽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纵菌,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天阐污,我揣著相機(jī)與錄音,去河邊找鬼咱圆。 笑死笛辟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的序苏。 我是一名探鬼主播手幢,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼忱详!你這毒婦竟也來了围来?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤匈睁,失蹤者是張志新(化名)和其女友劉穎监透,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體航唆,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡才漆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了佛点。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片醇滥。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖超营,靈堂內(nèi)的尸體忽然破棺而出鸳玩,到底是詐尸還是另有隱情,我是刑警寧澤演闭,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布不跟,位于F島的核電站,受9級(jí)特大地震影響米碰,放射性物質(zhì)發(fā)生泄漏窝革。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一吕座、第九天 我趴在偏房一處隱蔽的房頂上張望虐译。 院中可真熱鬧,春花似錦吴趴、人聲如沸漆诽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽厢拭。三九已至兰英,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間供鸠,已是汗流浹背畦贸。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留楞捂,地道東北人家制。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像泡一,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子觅廓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容