淺談 : iOS工程中哪些需要建立基類(MVC)
什麼是基類
首先我們來看一下基類的定義:通過繼承機制,能夠利用已有的資料型別來定義新的資料型別。所定義的新的資料型別不僅擁有新定義的成員,並且還同一時候擁有舊的成員。
基類的好處
首先在程式碼上面肯定是減少了程式碼量, 讓程式瘦身,其次能夠使程式碼的邏輯更加清晰等。不過,切記基類不能濫用,否則需求改變, 就可能面臨程式的很多地方都需要修改。個人覺得建立基類的原則之一應該有: 確定了這個程式碼肯定肯定不會隨著需求的改變而改變或者改動非常小。事實上,有時候在專案的功能已經實現了之後,再來進行很多程式碼的整理也是個不錯的選擇,這樣也能夠提升自己的經驗。貌似這就會涉及到重構的理念了。
哪些需要建立基類
以下我將列舉基本每個專案都需要建立的基類,可能不夠全面,希望您能給予補充。
一、Controller
1. UITabBarController
a.設定tabBar樣式;
b.初始化tabBarController控制的 controllers;
c.簽訂UITabBarControllerDelegate,實現協議方法,例如在使用者第二次點選tabItem的時候,需要重新整理介面的情況。
d.註冊tabItem切換時候的訊息等
- (void)initControllers
{
NSArray *tabControllerNames = @[@"HomePageViewController",
@"SearchViewController",
@"UserViewController"];
NSMutableArray *tabControllers = @[].mutableCopy;
[tabControllerNames enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *controllerName = obj;
Class class = NSClassFromString(controllerName);
if (class) {
[tabControllers addObject:[class new]];
}
}];
self.viewControllers = tabControllers;
}
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[RefreshViewController class]]) {
RefreshViewController *contrller = (RefreshViewController *)viewController;
[contrller startRefresh];
}
return YES;
}
2. UINavigationController
a.設定navigationBar樣式;
如果我們在整個工程中建立的是多個UINavigationController, 那麼在自定義的tabBar中, 就會初始化多個UINavigationController。 如果我們把設定樣式寫在了自定義的NC的viewDidLoad 裡面, 雖然我們設定的樣式是一樣的, 卻會走這個方法好幾次, 所以, 建議大家在NC中使用+ (void)initialize 這個類方法, 在這個方法裡面訂製樣式。這個類方法在整個app 的執行中, 不管你呼叫當前這個類多少次, 都會只走一次, 能夠提高程式的效率。appearanceWhenContainedIn這個方法裡面的class就是指定你想統一樣式的那些類。但是需要注意的是 , 如果你建立了ABNavigationController這個的子類, 那麼這個initialize方法就會走多次。 所以 記得進行判斷:
+ (void)initialize {
if (self == [ABNavigationController class]) {
UINavigationBar *bar = [UINavigationBar appearanceWhenContainedIn:[ABNavigationController class], nil];
[bar setBackgroundImage:[UIImage imageNamed:@"1"] forBarMetrics:UIBarMetricsDefault];
[bar setTitleTextAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:20],
NSForegroundColorAttributeName : [UIColor greenColor]}];
}
}
如果在專案中有遇到不同的樣式, 那麼可以在初始化UINavigationController的地方判斷。例如我的ABAreaViewController不想用上面那種樣式, 就可以像下面這樣寫了。
// 獲取nv
UINavigationController *nv = [[ABNavigationController alloc] initWithRootViewController:vc];
if ([vc isKindOfClass:[ABSpecialViewController class]]) {
nv = [[UINavigationController alloc] initWithRootViewController:vc];
return nv;
}
b. 設定返回手勢
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
self.interactivePopGestureRecognizer.enabled = YES;
}
NSLog(@"%@ did show", [viewController.class description]);
}
3. UIViewController
a. 介面的背景色;
b. 訊息提示的方法: 載入成功\失敗,提交成功\失敗,網路異常等
c. push controller的封裝等
4. 需要重新整理|資料請求的UIViewController
這個需要繼承?的UIViewController,顧名思義, 需要在這裡面寫新增addRefresh\startRefresh等。
5. 帶有tableView/collectionView佈局的
這個需要繼承? 。可以先通過懶載入或者一個方法初始化了tableView/collectionView,設定了基本引數和實現了基本的協議方法。子類作修改的時候只要重寫父類的方法就可以了。建立基類的時候 如果是tableview的style或者collectionview的flowlayout這種 可以寫一個方法 返回tableview 或者是返回flowlayout, 像下面這種:
- (UIScrollView *)refreshScrollView
{
UITableView *tableView = [self tableView];
tableView.delegate = self;
tableView.dataSource = self;
tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[tableView registerClass:[self tableViewCellClass] forCellReuseIdentifier:@"cell"];
return tableView;
}
- (UITableView *)tableView
{
return [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
}
- (Class)tableViewCellClass
{
return [UITableViewCell class];
}
不過對於collectionView的flowLayout, 可以通過重寫它的UICollectionViewDelegateFlowLayout的方法來設定引數,這個就依照個人喜好吧。但是切記:如果重寫了協議方法,那麼直接通過flowLayout.itemSize等這樣來設定的引數就會失效了。同tableview
在controller裡面的某些邏輯,我這裡可能不全面,可以借鑑這裡
二、UIView
1. UITableViewCell/UICollectionViewCell
a. 寫一個傳值的方法,子類繼承的時候, 直接實現傳值的方法就好。
- (void)configureWithItem:(id)item;
b. 不同的頁面可能會重複的利用一種cell 或者變化甚微, 這個時候,就再建立第二個基類, 可以將控制元件暴露在.h檔案中,如果是傳值的話, 就在.m中重寫父類方法;更改frame的話, 可以在layoutSubviews裡面更改,別忘了[super layoutSubviews ]
2. 自定義的檢視
對於tableView/collectionView頭檢視、輪播圖、時間選擇器等, 需要自定義的檢視, 需要傳值的, 可以像cell一樣,至少先寫一個傳值的方法備著。其他的視情況而定。還有帶有tableView/collectionView佈局的,也可以先實現協議方法,等待子類重寫。
3. 系統控制元件
對於label\button等, 做夜間模式的話,需要寫基類。如果你想程式碼更加簡潔,不妨向下面一樣,把原有方法再封裝一下,使用起來更簡單。
- (void)setNormalImage:(UIImage *)image
{
[self setImage:image forState:UIControlStateNormal];
}
[button setNormalImage:ImageNamed(@"icon_back")];
三、NSObject
1. API
除了某些引數不同之外, 其他需要提供給伺服器的引數很多都一致,
POST請求的話, 設定字典的引數;GET請求的話,設定拼接的字串。在API基類裡面寫資料請求的方法, 快取, 清理快取的方法。
2. model類
資料解析的時候,如果需要建立model類,這個時候, 如果剛好有些屬性以及容錯方法都是重複率比較高的,這個時候也可以建立一個基類。但是最好確定每個model都有這個屬性再建立基類,否則我建議就寫容錯方法吧。借鑑這裡
琪一可原創
相關文章
- iOS架構淺談從 MVC、MVP 到 MVVMiOS架構MVCMVPMVVM
- 淺談Python中的scrapy的安裝和建立工程。Python
- Eclipse Spring MVC工程的建立EclipseSpringMVC
- iOS底層原理 MVC、MVP、MVVM、分層設計淺談 — (13)iOSMVCMVPMVVM
- iOS 淺談 RunloopiOSOOP
- 淺談前端MVC與MVVC模式前端MVC模式
- 淺談MVC/MVP/MVVM模式(概述)MVCMVPMVVM模式
- iOS MVC、MVVM、MVP架構模式淺淺析iOSMVCMVVMMVP架構模式
- 淺談Java中的內部類Java
- 海外IT工程師淺談工程師
- 淺談 Trait 類AI
- 淺談 PHP 中異常類的使用PHP
- iOS探索:Block解析淺談iOSBloC
- 淺談Java抽象類Java抽象
- 淺談軟體工程中的程式碼評審軟體工程
- 淺談 iOS Device ID 的修改iOSdev
- 淺談微視推薦系統中的特徵工程特徵工程
- iOS tableView中的MVC、MVVMiOSViewMVCMVVM
- 淺談java內部類Java
- 淺談 Dart 類與類的基本方法Dart
- 淺談Python基礎Python
- 淺談Python中的bs4基礎Python
- iOS 淺談GPU及“App渲染流程”iOSGPUAPP
- 哪些情況下需要/不需要建立索引索引
- 人工智慧分類淺談人工智慧
- 淺談Java類中的變數初始化順序Java變數
- 深度聚類演算法淺談聚類演算法
- 談談JavaScript中建立物件(Object)JavaScript物件Object
- 淺談Android中LifecycleAndroid
- 淺談JavaScript中的thisJavaScript
- 淺談推進全站HTTPS專案-工程篇HTTP
- web前端工程師需要具備哪些要求?Web前端工程師
- [基礎] 淺談 JS Event LoopJSOOP
- Java基礎之淺談介面Java
- Java基礎之淺談集合Java
- 學Java需要哪些基礎?Java
- Java中父類方法重寫有哪些需要注意的?Java
- 深入淺出——MVCMVC
- iOS開發-MVCiOSMVC