項(xiàng)目包含多個(gè)storyboard文件的情況下衍菱,快速取出實(shí)例

storyboard可謂Xcode神器涂邀,比xib不知道高到哪里去了,也是apple一直推薦使用的侍芝。但是隨之而來(lái)的是兩個(gè)問題:一是研铆,多人開發(fā)時(shí)需要同時(shí)修改storyboard很容易導(dǎo)致文件沖突,二是州叠,storyboard文件里控制器太多棵红,電腦打開時(shí)特別卡和慢。我想這兩個(gè)問題是導(dǎo)致目前很多開發(fā)者選擇xib而不是storyboard的原因把咧栗。所以在iOS9以后出現(xiàn)了 Storyboard Reference逆甜。有點(diǎn)跑題。

一個(gè)解決辦法是致板,根據(jù)項(xiàng)目功能的劃分交煞,建立多個(gè)storyboard,各個(gè)模塊互不影響斟或。那么如何從許多個(gè)storyboard文件中快速取出我想要的那個(gè)控制器呢素征?下面應(yīng)該是大家使用的方法

UIStoryboard *sb = [UIStoryboard storyboardWithName:storyboardName bundle:[NSBundle mainBundle]];

UIViewController *vc = [sb instantiateViewControllerWithIdentifier:identifier];

關(guān)鍵是,storyboardName和identifier如果不對(duì),將會(huì)拋出異常稚茅。而且,app內(nèi)部那么多跳轉(zhuǎn)平斩,老是寫這樣的代碼亚享,不覺得煩么?

本文討論的是如何從多個(gè)storyboard中取出控制器實(shí)例绘面。不用管控制在哪個(gè)storyboard文件里欺税,只要 控制器設(shè)置identifier為類名就OK。

使用UIViewController的類別方法

#import <UIKit/UIKit.h>
@interface UIViewController (Storyboard)
+ (nullable instancetype)instanceFromStoryboardV2;
@end

使用 instanceFromStoryboardV2 取出以調(diào)用者類名為identifier的實(shí)例即可揭璃。如果沒有取到晚凿,返回nil

YouViewController *vc = [YouViewController instanceFromStoryboardV2];

具體實(shí)現(xiàn)步驟:

首先:檢查緩存里面有沒有保存這個(gè)identifier對(duì)應(yīng)的storyboard名字。如果有緩存瘦馍,直接從這個(gè)storyboard里面取
接著:獲取NSBunble的storyboard文件列表歼秽。篩選出storyboard文件名
第三:遍歷這個(gè)列表,嘗試取出實(shí)例情组。
最后:獲得實(shí)例后對(duì)storyboard名進(jìn)行緩存燥筷,同時(shí)返回實(shí)例
+ (nullable instancetype)instanceFromStoryboardV2
{
NSString *identifier = NSStringFromClass([self class]);

    // 取緩存的storyboard名
    NSCache *cache = [self cache];
    NSString *cacheStoryboardName = [cache objectForKey:identifier];
    if (cacheStoryboardName) {
        return [self tryTakeOutInstanceFromStoryboardNamed:cacheStoryboardName identifier:identifier];
    }

    // 未緩存,遍歷storyboard文件名列表院崇,開始嘗試取出實(shí)例肆氓。
    for (NSString *name in [self storyboardList]) {
        UIViewController *instance = [self tryTakeOutInstanceFromStoryboardNamed:name identifier:identifier];
        if (instance) {
            // 成功獲取實(shí)例后,對(duì)storyboard名進(jìn)行緩存
            [cache setObject:name forKey:identifier];
        return instance;
        }
    }
    return nil;
}

取出項(xiàng)目的storyboard文件列表

storyboard在NSBunble中是以storyboardc為后綴的底瓣。所以只要從NSBunble中查找所有storyboardc的文件就可以啦谢揪。
需要注意的是,xcode會(huì)額外自動(dòng)生成一個(gè)帶 ~iPhone 和 ~iPad 的storyboards文件捐凭。我們只需要storyboard文件名拨扶,所以這兩種文件我們需要忽略掉。

+ (nonnull NSArray*)storyboardList
{
     static NSArray *kBundleStoryboardNameList;
     static dispatch_once_t onceToken;
     dispatch_once(&onceToken, ^{
         NSMutableArray *tmp = [NSMutableArray array];

    /**
    *  找到所有storyboard文件茁肠。
    *  @warning 會(huì)忽略帶有 ~iphone(iPhone應(yīng)用)或 ~ipad(ipad應(yīng)用)標(biāo)志的 storyboard文件名
    */
        NSArray *list = [NSBundle pathsForResourcesOfType:@"storyboardc" inDirectory:[NSBundle mainBundle].resourcePath];
        for (NSString *path in list) {
            NSString *ext = [path lastPathComponent];
            NSString *name = [ext stringByDeletingPathExtension];
            if ([name rangeOfString:@"~"].location == NSNotFound) {

                [tmp addObject:name];
            }
          }

      kBundleStoryboardNameList = [NSArray arrayWithArray:tmp];
    });
    return kBundleStoryboardNameList;
}

嘗試取出實(shí)例

UIStoryboard的+storyboardWithName: bundle:方法如果name不正確屈雄,會(huì)拋出異常
-instantiateViewControllerWithIdentifier: 方法如果identifier在當(dāng)前UIStoryboard找不到,也會(huì)拋出異常官套。如果不做處理酒奶,會(huì)導(dǎo)致app崩潰。
所以這里采用了 try catch 對(duì)異常進(jìn)行捕獲奶赔。拋出異常時(shí)惋嚎,直接返回nil。
+ (nullable instancetype)tryTakeOutInstanceFromStoryboardNamed:(nonnull NSString *)storyboardName identifier:(nonnull NSString *)identifier
{
if (!storyboardName || !identifier) {
return nil;
}

    @try {
        UIStoryboard *sb = [UIStoryboard storyboardWithName:storyboardName bundle:[NSBundle mainBundle]];
        UIViewController *vc = [sb instantiateViewControllerWithIdentifier:identifier];
        return vc;
    }
    @catch (NSException *exception) {
        return nil;
    }
     @finally {
        
    }  
}

緩存

+ (NSCache *)cache
{
    static NSCache *cache;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        cache = [[NSCache alloc] init];
    });
    return cache;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末站刑,一起剝皮案震驚了整個(gè)濱河市另伍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖摆尝,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件温艇,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡堕汞,警方通過查閱死者的電腦和手機(jī)勺爱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)讯检,“玉大人琐鲁,你說(shuō)我怎么就攤上這事∪俗疲” “怎么了围段?”我有些...
    開封第一講書人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)投放。 經(jīng)常有香客問我奈泪,道長(zhǎng),這世上最難降的妖魔是什么灸芳? 我笑而不...
    開封第一講書人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任段磨,我火速辦了婚禮,結(jié)果婚禮上耗绿,老公的妹妹穿的比我還像新娘苹支。我一直安慰自己,他們只是感情好误阻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開白布债蜜。 她就那樣靜靜地躺著,像睡著了一般究反。 火紅的嫁衣襯著肌膚如雪寻定。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,698評(píng)論 1 305
  • 那天精耐,我揣著相機(jī)與錄音狼速,去河邊找鬼。 笑死卦停,一個(gè)胖子當(dāng)著我的面吹牛向胡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播惊完,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼僵芹,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了小槐?” 一聲冷哼從身側(cè)響起拇派,我...
    開封第一講書人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后件豌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疮方,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年茧彤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了骡显。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡棘街,死狀恐怖蟆盐,靈堂內(nèi)的尸體忽然破棺而出承边,到底是詐尸還是另有隱情遭殉,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布博助,位于F島的核電站险污,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏富岳。R本人自食惡果不足惜蛔糯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窖式。 院中可真熱鬧蚁飒,春花似錦、人聲如沸萝喘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)阁簸。三九已至爬早,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間启妹,已是汗流浹背筛严。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留饶米,地道東北人桨啃。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像檬输,于是被迫代替她去往敵國(guó)和親优幸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

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

  • *面試心聲:其實(shí)這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來(lái)就是把...
    Dove_iOS閱讀 27,150評(píng)論 30 470
  • 1.badgeVaule氣泡提示 2.git終端命令方法> pwd查看全部 >cd>ls >之后桌面找到文件夾內(nèi)容...
    i得深刻方得S閱讀 4,667評(píng)論 1 9
  • 1.自定義控件 a.繼承某個(gè)控件 b.重寫initWithFrame方法可以設(shè)置一些它的屬性 c.在layouts...
    圍繞的城閱讀 3,391評(píng)論 2 4
  • 一褪猛、深復(fù)制和淺復(fù)制的區(qū)別网杆? 1、淺復(fù)制:只是復(fù)制了指向?qū)ο蟮闹羔槪磧蓚€(gè)指針指向同一塊內(nèi)存單元碳却!而不復(fù)制指向?qū)ο蟮?..
    iOS_Alex閱讀 1,378評(píng)論 1 27
  • 有一個(gè)人队秩,他長(zhǎng)著一張國(guó)字臉,總喜歡穿著一件襯衫和牛仔褲昼浦,一副黑色半框眼鏡馍资,遮住的是閃著智慧之光的眼睛,你猜他...
    智智123閱讀 346評(píng)論 0 2