App-快速搭建項(xiàng)目框架-AppDelegate入口

AppDelegate組件化

AppDelegate瘦身

  • AppDelegate是App的入口,對(duì)于開(kāi)發(fā)耦合性來(lái)說(shuō)憔维,AppDelegate除了負(fù)責(zé)應(yīng)用生命周期之外淹辞,盡量不要有大量的代碼地沮。
  • 但是在iOS 實(shí)際開(kāi)發(fā)過(guò)程中攀例,很多人習(xí)慣將全局變量定義在 AppDelegate 中,會(huì)導(dǎo)入比如推送皿曲、統(tǒng)計(jì)唱逢、分享、三方登陸屋休、地圖等組件坞古,但如此這般,AppDelegate就變得更加臃腫劫樟。在大型項(xiàng)目中痪枫,想要解除耦合和模塊化時(shí),都不利于AppDelegate的維護(hù)叠艳。
  • 將很多全局變量放在AppDelegate上奶陈,將AppDelegate作為一個(gè)依賴(lài)中心點(diǎn),雖然很多模塊可以訪問(wèn)全局變量附较,但會(huì)產(chǎn)生相互依賴(lài)吃粒,不利于模塊化開(kāi)發(fā);
  • 不同的模塊拒课,會(huì)根據(jù)需要在AppDelegate的不同生命周期方法中徐勃,調(diào)用各種方法。比如在程序啟動(dòng)時(shí)在application:didFinishLaunchingWithOptions:內(nèi)注冊(cè)一個(gè)初始化方法早像;

組件化分開(kāi)引入

創(chuàng)建繼承NSObject的AppModuleManager單利類(lèi)

AppModuleManager.h文件

#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@import UIKit;
@import UserNotifications;
@protocol AppModuleManagerDelegate <UIApplicationDelegate, UNUserNotificationCenterDelegate>
@end
@interface AppModuleManager : NSObject<UIApplicationDelegate, UNUserNotificationCenterDelegate>
+ (instancetype)sharedInstance;
- (void)loadModulesWithPlistFile:(NSString *)plistFile;
- (NSArray<id<AppModuleManagerDelegate>> *)allModules;
@end
NS_ASSUME_NONNULL_END

AppModuleManager.m文件

#import "AppModuleManager.h"
@interface AppModuleManager ()

@property (nonatomic, strong) NSMutableArray<id<AppModuleManagerDelegate>> *modules;

@end
@implementation AppModuleManager
+ (instancetype)sharedInstance
{
    static AppModuleManager *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[[self class] alloc] init];
    });
    return instance;
}
- (NSMutableArray<id<AppModuleManagerDelegate>> *)modules
{
    if (!_modules) {
        _modules = [NSMutableArray array];
    }
    return _modules;
}
- (void)addModule:(id<AppModuleManagerDelegate>) module
{
    if (![self.modules containsObject:module]) {
        [self.modules addObject:module];
    }
}
- (void)loadModulesWithPlistFile:(NSString *)plistFile
{
    NSArray<NSString *> *moduleNames = [NSArray arrayWithContentsOfFile:plistFile];
    for (NSString *moduleName in moduleNames) {
        id<AppModuleManagerDelegate> module = [[NSClassFromString(moduleName) alloc] init];
        [self addModule:module];
    }
}
- (NSArray<id<AppModuleManagerDelegate>> *)allModules
{
    return self.modules;
}
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module applicationDidFinishLaunching:application];
        }
    }
}
#pragma mark - State Transitions / Launch time:
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module application:application willFinishLaunchingWithOptions:launchOptions];
        }
    }
    return YES;
}
#pragma mark - 程序第一次加載完畢僻肖,就會(huì)調(diào)用此方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module application:application didFinishLaunchingWithOptions:launchOptions];
        }
    }
    return YES;
}
#pragma mark - 程序?qū)⒁ソ裹c(diǎn) - 不能交互
- (void)applicationWillResignActive:(UIApplication *)application
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module applicationWillResignActive:application];
        }
    }
}
#pragma mark - 程序已經(jīng)進(jìn)入后臺(tái),通常我們會(huì)在這個(gè)時(shí)候保存數(shù)據(jù)
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module applicationDidEnterBackground:application];
        }
    }
}
#pragma mark - 程序?qū)⒁M(jìn)入前臺(tái)卢鹦,通常我們會(huì)在這個(gè)時(shí)候恢復(fù)數(shù)據(jù)
- (void)applicationWillEnterForeground:(UIApplication *)application
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module applicationWillEnterForeground:application];
        }
    }
}
#pragma mark - 程序已經(jīng)獲取焦點(diǎn) - 可以交互
- (void)applicationDidBecomeActive:(UIApplication *)application
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module applicationDidBecomeActive:application];
        }
    }
}
#pragma mark - 程序掛了臀脏,將要完全退出。
- (void)applicationWillTerminate:(UIApplication *)application
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module applicationWillTerminate:application];
        }
    }
}
#pragma mark - 程序接收到內(nèi)存警告
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module applicationDidReceiveMemoryWarning:application];
        }
    }
}
#pragma mark - 程序接收到url處理
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        if ([module respondsToSelector:_cmd]) {
            return  [module application:application handleOpenURL:url];
        }
#pragma clang diagnostic pop
    }
    return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        if ([module respondsToSelector:_cmd]) {
            return  [module application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
        }
#pragma clang diagnostic pop
    }
    return YES;
}
#pragma clang diagnostic pop

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options API_AVAILABLE(ios(9.0))
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            return  [module application:app openURL:url options:options];
        }
    }
    return YES;
}



#pragma mark - Handling Remote Notification
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
        }
    }
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module application:application didFailToRegisterForRemoteNotificationsWithError:error];
        }
    }
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
        }
    }
}
#pragma mark - Handling Local Notification
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module application:application didReceiveRemoteNotification:userInfo];
        }
    }
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)(void))completionHandler
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module application:application handleActionWithIdentifier:identifier forRemoteNotification:userInfo completionHandler:completionHandler];
        }
    }
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)(void))completionHandler
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module application:application handleActionWithIdentifier:identifier forRemoteNotification:userInfo withResponseInfo:responseInfo completionHandler:completionHandler];
        }
    }
}
#pragma mark - Handling Local Notification
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification
         withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
API_AVAILABLE(ios(10.0)){
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module userNotificationCenter:center willPresentNotification:notification withCompletionHandler:completionHandler];
        }
    }
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler
API_AVAILABLE(ios(10.0)){
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
        }
    }
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module application:application didReceiveLocalNotification:notification];
        }
    }
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)(void))completionHandler
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module application:application handleActionWithIdentifier:identifier forLocalNotification:notification completionHandler:completionHandler];
        }
    }
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)(void))completionHandler
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module application:application handleActionWithIdentifier:identifier forLocalNotification:notification withResponseInfo:responseInfo completionHandler:completionHandler];
        }
    }
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module application:application didRegisterUserNotificationSettings:notificationSettings];
        }
    }
}

#pragma mark - Handling Continuing User Activity and Handling Quick Actions

- (BOOL)application:(UIApplication *)application willContinueUserActivityWithType:(NSString *)userActivityType
{
    BOOL result = NO;
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            result = result || [module application:application willContinueUserActivityWithType:userActivityType];
        }
    }
    return result;
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
    BOOL result = NO;
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            result = result || [module application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
        }
    }
    return result;
}
- (void)application:(UIApplication *)application didUpdateUserActivity:(NSUserActivity *)userActivity
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module application:application didUpdateUserActivity:userActivity];
        }
    }
}
- (void)application:(UIApplication *)application didFailToContinueUserActivityWithType:(NSString *)userActivityType error:(NSError *)error
{
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module application:application didFailToContinueUserActivityWithType:userActivityType error:error];
        }
    }
}
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL succeeded))completionHandler
API_AVAILABLE(ios(9.0)){
    for (id<AppModuleManagerDelegate> module in self.modules) {
        if ([module respondsToSelector:_cmd]) {
            [module application:application performActionForShortcutItem:shortcutItem completionHandler:completionHandler];
        }
    }
}
@end

// AppModulesRegister.plist


截屏2021-04-18 下午11.48.23.png

AppDelegate.m中實(shí)現(xiàn)

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {


    NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"AppModulesRegister" ofType:@"plist"];
    AppModuleManager *manager = [AppModuleManager sharedInstance];
    [manager loadModulesWithPlistFile:plistPath];
    [manager application:application willFinishLaunchingWithOptions:launchOptions];
  return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [UIApplication sharedApplication].statusBarHidden = NO;
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window  makeKeyAndVisible];
    [[AppModuleManager sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
    return YES;
}

在需要的方法實(shí)現(xiàn)

AppModulePush.h文件
#import <Foundation/Foundation.h>
#import "AppModuleManager.h"
NS_ASSUME_NONNULL_BEGIN
@interface AppModulePush : NSObject<AppModuleManagerDelegate>
@end
NS_ASSUME_NONNULL_END

AppModulePush.m文件
#pragma mark - 程序?qū)⒁ソ裹c(diǎn) - 不能交互
- (void)applicationWillResignActive:(UIApplication*)application
{
    [[AppModuleManager sharedInstance] applicationWillResignActive:application];
}
#pragma mark - 程序已經(jīng)進(jìn)入后臺(tái)冀自,通常我們會(huì)在這個(gè)時(shí)候保存數(shù)據(jù)
- (void)applicationDidEnterBackground:(UIApplication*)application
{
    [[AppModuleManager sharedInstance] applicationDidEnterBackground:application];
}
#pragma mark - 程序?qū)⒁M(jìn)入前臺(tái)揉稚,通常我們會(huì)在這個(gè)時(shí)候恢復(fù)數(shù)據(jù)
- (void)applicationWillEnterForeground:(UIApplication*)application
{
    [[AppModuleManager sharedInstance] applicationWillEnterForeground:application];
}
#pragma mark - 程序已經(jīng)獲取焦點(diǎn) - 可以交互
- (void)applicationDidBecomeActive:(UIApplication*)application
{
    [[AppModuleManager sharedInstance] applicationDidBecomeActive:application];
}
#pragma mark - 程序掛了,將要完全退出凡纳。
- (void)applicationWillTerminate:(UIApplication*)application
{
    [[AppModuleManager sharedInstance] applicationWillTerminate:application];
}
#pragma mark - 程序接收到內(nèi)存警告
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
    [[AppModuleManager sharedInstance] applicationDidReceiveMemoryWarning:application];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者帝蒿。
  • 序言:七十年代末荐糜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌暴氏,老刑警劉巖延塑,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異答渔,居然都是意外死亡关带,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)沼撕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)宋雏,“玉大人,你說(shuō)我怎么就攤上這事务豺∧プ埽” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵笼沥,是天一觀的道長(zhǎng)蚪燕。 經(jīng)常有香客問(wèn)我,道長(zhǎng)奔浅,這世上最難降的妖魔是什么馆纳? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮汹桦,結(jié)果婚禮上鲁驶,老公的妹妹穿的比我還像新娘。我一直安慰自己营勤,他們只是感情好灵嫌,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著葛作,像睡著了一般寿羞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赂蠢,一...
    開(kāi)封第一講書(shū)人閱讀 52,246評(píng)論 1 308
  • 那天绪穆,我揣著相機(jī)與錄音,去河邊找鬼虱岂。 笑死玖院,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的第岖。 我是一名探鬼主播难菌,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蔑滓!你這毒婦竟也來(lái)了郊酒?” 一聲冷哼從身側(cè)響起遇绞,我...
    開(kāi)封第一講書(shū)人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎燎窘,沒(méi)想到半個(gè)月后摹闽,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡褐健,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年付鹿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚜迅。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡舵匾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出慢叨,到底是詐尸還是另有隱情纽匙,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布拍谐,位于F島的核電站烛缔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏轩拨。R本人自食惡果不足惜践瓷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望亡蓉。 院中可真熱鬧晕翠,春花似錦、人聲如沸砍濒。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)爸邢。三九已至樊卓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間杠河,已是汗流浹背碌尔。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留券敌,地道東北人唾戚。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像待诅,于是被迫代替她去往敵國(guó)和親叹坦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

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

  • 嚴(yán)格來(lái)講卑雁,AppDelegate除了負(fù)責(zé)應(yīng)用生命周期之外募书,不應(yīng)該再有多余的責(zé)任轧钓。 但在iOS 實(shí)際開(kāi)發(fā)過(guò)程中,很多...
    CoderDancer閱讀 4,009評(píng)論 7 20
  • 原文鏈接http://www.cocoachina.com/ios/20161103/17938.html?utm...
    wycandyy閱讀 2,336評(píng)論 0 22
  • 前言: 之前看了Casa大神的架構(gòu)設(shè)計(jì)文章锐膜,醍醐灌頂,一直想開(kāi)個(gè)系列文章記錄一下(這次就做個(gè)小小搬運(yùn)工弛房,別打臉)道盏,...
    M_慕宸閱讀 5,678評(píng)論 1 13
  • 前言:框架是一個(gè)APP的骨骼,核心文捶,一個(gè)項(xiàng)目的所有功能以及以后的迭代都是在此基礎(chǔ)上進(jìn)行的荷逞,它是開(kāi)展一個(gè)項(xiàng)目的至關(guān)重...
    CoderLGL閱讀 1,794評(píng)論 0 5
  • 架構(gòu)圖: 架構(gòu)原則:易讀性、易維護(hù)性粹排、易擴(kuò)展性种远。 一、思考 做好一件事顽耳,花在思考上的時(shí)間應(yīng)該多于執(zhí)行坠敷。 首先根據(jù)產(chǎn)...
    Young_LI閱讀 746評(píng)論 0 1