讓列表默認(rèn)占位圖實現(xiàn)起來更優(yōu)雅

老規(guī)矩窄赋,一圖勝千言

無數(shù)據(jù)默認(rèn)加載圖.gif

Demo下載地址

先嘮叨幾句

最近也是忙于項目進(jìn)度,學(xué)習(xí)時間被大大的壓縮了下來,距離上次寫文章已經(jīng)過去了整整倆月時間。項目進(jìn)度已經(jīng)趕的差不多了所以抽空將項目中遇到的問題及解決方法記錄一下。

出現(xiàn)的問題

隨著項目漸漸的接近尾聲,在項目中列表無數(shù)據(jù)展示成為了令人頭疼的問題欢摄。如何優(yōu)雅且更智能的讓占位圖在列表無數(shù)據(jù)時自動展示出來,我剛開始的做法是將圖片和提示文字寫在一個自定義 view 上笋粟,每次當(dāng)網(wǎng)絡(luò)請求完成都要去判斷當(dāng)前列表是否有數(shù)據(jù)怀挠,如果沒有數(shù)據(jù)則將 view 加載到列表中;如果有數(shù)據(jù)則將 view 隱藏掉害捕。這樣暴露出很嚴(yán)重的問題是:每個列表對應(yīng)一個相應(yīng)的自定義展示 view 對象绿淋,如果一個頁面有好幾個列表,那么對自定義展示圖的控制就沒難么容易了尝盼,而且每次都要計算占位圖的frame或者當(dāng)上拉加載更多時沒有請求到數(shù)據(jù)并且當(dāng)前列表中有上次請求的數(shù)據(jù)吞滞,如果用當(dāng)前請求的數(shù)據(jù)去判斷 view 的隱藏與否是不正確的,所以還要拿到當(dāng)前列表的總數(shù)據(jù)去判斷。

我曾在網(wǎng)上找到了一個很優(yōu)秀的三方框架DZNEmptyDataSet 下載下來看了一下不是很符合自己的要求所以并沒有將其放入自己的項目中(有興趣的同學(xué)可以下載試玩一下)裁赠。在12月21日那天在掘金網(wǎng)上無意瀏覽了一個博客感覺很棒殿漠,很符合自己的需求所以就按照博主的 Demo 重寫并優(yōu)化了一下用在了自己的項目中,下面對demo 中的部分代碼進(jìn)行講解佩捞。

說一說 category

我在項目中喜歡用分類 為控制器绞幌、view 或者 NSObject 類型等等擴(kuò)展屬性和方法,這樣既不與別人寫的代碼沖突而且實現(xiàn)起來也更優(yōu)雅一忱。說起 category 必定與 runtime 密不可分莲蜘,對 runtime 的使用我其實也只會一點點而且大部分都是什么時候用什么時候查,好了帘营,回歸正題票渠。

部分代碼講解

重寫+(void)load方法,我們在平時寫自定 view 時都會在.m 中重寫一下-(instancetype)init或者- (instancetype)initWithFrame:(CGRect)frame方法來初始化控件芬迄,而tableview或者collectionViewreloaddata時也會調(diào)用load方法问顷。如果在列表 reload 的時候?qū)α斜韮?nèi)的數(shù)據(jù)進(jìn)行檢測來達(dá)到是否展示占位圖的效果,可所謂是一舉兩得啊薯鼠。

一言不合就貼一手代碼。

+(void)load{
    //為了保證該對象的實例化方法只交換一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Method reloadData = class_getInstanceMethod(self, @selector(reloadData));
        Method m_reloadData = class_getInstanceMethod(self, @selector(m_reloadData));
        method_exchangeImplementations(reloadData, m_reloadData);
        Method delloc = class_getInstanceMethod(self, NSSelectorFromString(@"dealloc"));
        Method m_delloc = class_getInstanceMethod(self, @selector(m_delloc));
        method_exchangeImplementations(delloc, m_delloc);
    });
}

從代碼中主要用到runtime兩種方法:1.獲取當(dāng)前對象實例化方法class_getInstanceMethod 2.方法交換method_exchangeImplementations械蹋;獲取的方法分別是reloadDatadelloc這兩種方法出皇,獲取delloc方法主要是為了移除監(jiān)聽,下面再說這個方法哗戈。來看一下reload方法的實現(xiàn):

-(void)m_reloadData{
    [self m_reloadData];
    //第一次忽略,不展示占位圖
    if (!self.isInitFinish) {
        [self m_havingData:YES];
        self.isInitFinish = YES;
        return;
    }
    //  刷新完成之后檢測數(shù)據(jù)量
    dispatch_async(dispatch_get_main_queue(), ^{
        NSInteger numberOfSections = [self numberOfSections];
        //如果沒有數(shù)據(jù)則調(diào)用底下方法來創(chuàng)建占位圖
        BOOL havingData = NO;
        for (NSInteger i = 0; i < numberOfSections; i++) {
            if ([self numberOfRowsInSection:i] > 0) {
                havingData = YES;
                break;
            }
        }
        [self m_havingData:havingData];
    });
}

不知道大家看完這個方法是不是腦子中已經(jīng)浮現(xiàn)出創(chuàng)建占位圖的大致邏輯了郊艘,此方法中還有一個小小的彩蛋不知道大家注意到?jīng)]有,因為對 runtime 的不了解唯咬,反正我當(dāng)時看的時候沒有注意到纱注,后來才發(fā)現(xiàn)這一點:在上面那個方法中有沒有注意到第一行代碼[self m_reloadData];在自己中調(diào)用自己?這不就成死循環(huán)了嗎胆胰?我剛開始也并不理解狞贱,我也并沒有去查資料,我自己的理解是這樣的:在reload里面利用method_exchangeImplementations方法將 tableview 的reloadm_reloadData進(jìn)行交換蜀涨,每次獲取到數(shù)據(jù)去刷新列表時reloadData方法進(jìn)行的動態(tài)替換瞎嬉,也就是說調(diào)用 tableview 的reloadData 實則調(diào)用的是m_reloadData,而m_reloadData做的主要工作就是控制占位圖的顯示與隱藏并沒有去刷新列表厚柳,那列表怎么刷新把踉妗?那就是調(diào)用m_reloadData實則是調(diào)用的是列表的reloadData别垮,所以才會出現(xiàn)上面方法中所寫的方法便监。是不是有點繞碳想,上面所述純粹個人見解。

如何讓不同列表有不同占位圖

在創(chuàng)建 tableview 或 collectionView 時老充,實現(xiàn)與之對應(yīng)的代理是必不可少的一步啡浊。那代理有沒有可能幫到我們呢巷嚣?答案是肯定的钳吟。說一句題外話:入行有段時間了红且,漸漸地對代碼有了新的認(rèn)識嗤放,一個 app 的構(gòu)成就是內(nèi)部收發(fā)消息壁酬,無論你干什么你都需要將消息傳出去舆乔,接收消息,反饋消息吊宋,請仔細(xì)想想無論代碼世界還是現(xiàn)實生活贫母,消息的機(jī)制被用到萬事萬物中腺劣¢僭回正題趾断,說了句題外話的目的就是為了說明 app 內(nèi)無論是收消息還是找消息都是通過Selector去做的芋酌,我們可以利用 tableview 的代理對象來達(dá)到這個目的脐帝。

來看代碼

@protocol MTableViewDelegate <NSObject>
//如果不在當(dāng)前類中聲明這些方法炸站,當(dāng)用 self.delgate 查找這些方法時會出現(xiàn)黃色的警告
@optional
- (UIView *)m_noDataView; //完全自定義占位圖
- (UIImage *)m_noDataViewImage; //使用默認(rèn)占位圖, 提供一張圖片,    可不提供, 默認(rèn)不顯示
- (NSString *)m_noDataViewMessage; //使用默認(rèn)占位圖, 提供顯示文字,    可不提供, 默認(rèn)為暫無數(shù)據(jù)
- (UIColor *)m_noDataViewMessageColor; //使用默認(rèn)占位圖, 提供顯示文字顏色, 可不提供, 默認(rèn)為灰色
- (NSNumber *)m_noDataViewCenterYOffset; //使用默認(rèn)占位圖, CenterY 向下的偏移量
@end

我們在分類.m 中寫上這些方法旱易,然后利用UITableViewDelegate去檢測這些方法是否存在

//判斷是否響應(yīng)圖片代理
BOOL isImg = [self.delegate    respondsToSelector:@selector(m_noDataViewImage)];

請注意這里的self.delegate這句代碼檢測的已經(jīng)不是當(dāng)前類中的方法了阀坏,而是當(dāng)你初始化 tableview 時將xxx.delegate = self;這樣賦值是代理的對象已經(jīng)是當(dāng)前類了忌堂,所以這個方法是否響應(yīng)浸船,檢索的方法應(yīng)該是你所賦值的類中。我們常說的一句話就是面向?qū)ο?/strong>登淘,我認(rèn)為:類也是對象,類的 category 也是一個對象耍鬓,類與對象沒什么區(qū)別流妻,類是對象的抽象化绅这,對象是類的具體化,具體的事物是對象, 將具有相同或相似性質(zhì)的對象的屬性或方法抽象出來便是類匆篓。如果你分不清什么是類什么是對象鸦概,那么你在寫代碼的時候肯定會遇到不必要的麻煩甩骏。

我們知道 tableview 有個屬性叫backgroundView谨设,我們可以很巧妙的將自定義的占位視圖給這個屬性缎浇,反正平時這個屬性大家也不是很常用二蓝。當(dāng)你將自定義視圖給self.backgroundView = xxx時指厌,發(fā)現(xiàn)你滾動列表時backgroundView是固定不動的鸥诽,那有什么辦法能讓視圖跟著列表一起滾動起來牡借,可以設(shè)置監(jiān)聽钠龙,監(jiān)聽 tableview 的frame碴里,在 tableview 滾動contentOffset 改變時, backgroundView 的frame.origin.y也是同步改變的, 所以我們看起來無論 TableView 怎么滾動占位圖都是無動于衷的, 如果我們想讓占位圖跟隨滾動的話, 只要取消掉backgroundView 的 frame.origin.y 的同步更新就好了, 也就是說要保證 frame.origin.y 的值一直為0咬腋,具體的可以看下 demo 實現(xiàn)根竿。設(shè)置監(jiān)聽必定需要移除監(jiān)聽蠢壹,如果不在delloc中移除監(jiān)聽的話图贸,由于監(jiān)聽會一直存在必定造成崩潰疏日,所以才動態(tài)的去替換delloc方法沟优。我在 demo 中并沒有去移除監(jiān)聽挠阁,而是在NSObject+MAdd這個文件中調(diào)用了

- (void)m_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

這個方法溯饵,此方法可在對象消失后自動移除監(jiān)聽隘谣。具體實現(xiàn)詳見 Demo寻歧。

不想要占位圖?

如果在實現(xiàn) tableview 的代理文件中逗概,不實現(xiàn)上述的幾個方法就不會加載占位圖弟晚,demo 已在這一部分做了處理忘衍。其實逾苫,你還可以為占位視圖添加些許方法:提示文字的字體大小、提示文字的富文本屬性枚钓、加載圖片的動畫等等铅搓,這些需要自行實現(xiàn)。

列表有tableHeaderView怎么辦搀捷?

有的列表是有tableHeaderView的情況下星掰,上面的方法是行不通的多望,因為tableHeaderView如果過高的情況下會把backgroundView蓋住,導(dǎo)致占位圖無法顯示氢烘,有興趣的小伙伴可以試一下我說的這種情況蜀踏。我的做法是:如果tableHeaderView的高度超過了當(dāng)前tableview高度的一半時將占位圖加載到tableFooterView上,前提是當(dāng)前 tableview 的 fotterview 沒有內(nèi)容钳榨。如果高度沒有超過一半則還加載到backgroundView上昭卓。如果你有更好的方法請及時聯(lián)系我伙菊。

聊一聊 runtime 的簡單用法

在我上一篇關(guān)于列表的預(yù)加載文章中簡單敘述了一下關(guān)于 runtime 的基本用法兴枯,我現(xiàn)在將里面的細(xì)節(jié)再一一扣一下躺坟。

在寫 category 類的分類時匣摘,經(jīng)常為現(xiàn)有的類添加私有變量或者為現(xiàn)有的類添加共有屬性供外部訪問擦囊。寫過分類的朋友都知道在寫分類屬性的時候涧郊,編譯器會給出一個黃色警告幌陕,比如我為某個分類創(chuàng)建一個為test屬性會報如下警告:

Property 'test' requires method 'setTest:' to be defined 
- use @dynamic or provide a method implementation in this category

簡單翻譯一下這段話:test屬性,必須實現(xiàn)setTest:或?qū)⑵錁?biāo)記為@dynamic或者在此類里提供方法實現(xiàn)失暴,即 get 方法现恼。

@dynamic 是什么喳逛?

我們都知道當(dāng)你@property一個屬性時,編譯器會自動給你實現(xiàn)settergetter方法砖织,自動為你實現(xiàn)方法的為@synthesize,而與之對應(yīng)的則是@dynamic块请。當(dāng)一個屬性被標(biāo)記為@dynamic 時海渊,此時編譯器就認(rèn)為該屬性的 setter和 getter 方法由用戶自己實現(xiàn)哲鸳,不自動生成婿奔。如果該屬性被標(biāo)記為@dynamic就算沒有實現(xiàn) setter 和 getter 方法編譯也會通過,如果當(dāng)程序運行到xxx.test = xxx時挖腰,由于缺少與其相對應(yīng)的 setter 方法導(dǎo)致崩潰翰蠢;或者xxx *pro = test時,由于缺少 getter 方法同樣會導(dǎo)致崩潰梁沧。在編譯時沒有問題檀何,運行時才執(zhí)行相應(yīng)的方法,這就是動態(tài)綁定,即 runtime 運行時频鉴。

在分類中實現(xiàn) setter 和 getter 方法是用 runtime 中的objc_setAssociatedObjectobjc_getAssociatedObject栓辜,來看一下實現(xiàn)方法

-(void)setTest:(NSString *)test{
    objc_setAssociatedObject(self, @selector(test), test, OBJC_ASSOCIATION_RETAIN);
}
-(NSString *)test{
    return objc_getAssociatedObject(self, _cmd);
}

在objc_setAssociatedObject會涉及到四個參數(shù),分別是object砚殿、key啃憎、value芝囤、policy

1.object似炎,要關(guān)聯(lián)的對象即 self

2.key,這個 key 值必須保證是一個對象級別的唯一常量與創(chuàng)建 tablviewcell 所創(chuàng)建的 ID 類似悯姊;

一般來說羡藐,有以下三種推薦的 key 值:

① 聲明static const char * key_m_test = "key_m_test";使用 &key_m_test 作為 key 值這個是需要加&符號獲取地址;

② 聲明 static const void * key_m_test = "key_m_test" ,使用key_m_test 作為 key 值悯许;以上兩種寫法我認(rèn)為是一個是 C 寫法仆嗦,一個為 OC 寫法

③ 用 selector ,使用 getter 方法的名稱作為 key 值先壕。因為它省掉了一個變量名瘩扼,非常優(yōu)雅地解決了命名問題。

3.value 即當(dāng)前屬性的值

4.policy 關(guān)聯(lián)策略

 typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
     OBJC_ASSOCIATION_ASSIGN = 0,//弱引用對象
     OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, //強(qiáng)引用對象且為非原子操作
     OBJC_ASSOCIATION_COPY_NONATOMIC = 3,//復(fù)制關(guān)聯(lián)對象且為非原子操作
     OBJC_ASSOCIATION_RETAIN = 01401,//強(qiáng)引用對象且為原子操作         
     OBJC_ASSOCIATION_COPY = 01403//復(fù)制關(guān)聯(lián)對象為原子操作
 };
 將前三種翻譯過來即:
 @property (nonatomic, assign)
 @property (nonatomic, strong)
 @property (nonatomic, copy)

細(xì)心的同學(xué)會發(fā)現(xiàn)垃僚,在寫 getter 方法是用到了一個_cmd集绰,自己寫一下發(fā)現(xiàn)他是一個SEL類型,這個_cmd是什么谆棺?以下為我查閱的資料:

Objective-C中的方法默認(rèn)被隱藏了兩個參數(shù):self_cmd栽燕。self指向?qū)ο蟊旧恚琠cmd指向方法本身改淑。舉兩個例子來說明:

例一:

- (NSString *)name

這個方法實際上有兩個參數(shù):self和_cmd碍岔。

例二:

- (void)setValue:(int)value

這個方法實際上有三個參數(shù):self, _cmd和value。被指定為動態(tài)實現(xiàn)的方法的參數(shù)類型有如下的要求:

A.第一個參數(shù)類型必須是id(就是self的類型)

B.第二個參數(shù)類型必須是SEL(就是_cmd的類型)

C.從第三個參數(shù)起朵夏,可以按照原方法的參數(shù)類型定義蔼啦。

舉兩個例子來說明:

例一:setHeight:(CGFloat)height中的參數(shù)height是浮點型的,所以第三個參數(shù)類型就是f仰猖。

例二:再比如setName:(NSString *)name中的參數(shù)name是字符串類型的询吴,所以第三個參數(shù)類型就是@類型

有一句代碼是xxx.name = @"xxx";程序運行到這里時,會去.m中尋找setName:這個賦值方法亮元。但是.m里并沒有這個方法猛计,于是程序進(jìn)入methodSignatureForSelector:中進(jìn)行消息轉(zhuǎn)發(fā)。執(zhí)行完之后爆捞,以"v@:@"作為方法簽名類型返回奉瘤。

這里v@:@是什么東西呢?實際上,這里的第一個字符v代表函數(shù)的返回類型是void盗温,(后面三個字符分別self, _cmd, name這三個參數(shù)的類型id, SEL, NSString藕赞。

接著程序進(jìn)入forwardInvocation方法。得到的key為方法名稱setName:卖局,然后利用[invocationgetArgument:&obj atIndex:2];獲取到參數(shù)值斧蜕,這里是“xxx”。這里的index為什么要取2呢砚偶?如前面分析批销,第0個參數(shù)是self,第1個參數(shù)是_cmd染坯,第2個參數(shù)才是方法后面帶的那個參數(shù)均芽。

最后利用一個可變字典來賦值。這樣就完成了整個setter過程单鹿。

有一句代碼是 NSLog(@"%@", xxx.test);掀宋,程序運行到這里時,會去.m中尋找name這個取值方法 仲锄。但是.m里并沒有這個取值方法劲妙,于是程序進(jìn)入methodSignatureForSelector:中進(jìn)行消息轉(zhuǎn)發(fā)。執(zhí)行完之后儒喊,以"@@:"作為方法簽名類型返回镣奋。這里第一字符@代表函數(shù)返回類型NSString,第二個字符@代表self的類型id澄惊,第三個字符:代表_cmd的類型SEL唆途。

接著程序進(jìn)入forwardInvocation方法。得到的key為方法名稱name掸驱。

最后根據(jù)這個key從字典里獲取相應(yīng)的值肛搬,這樣就完成了整個getter過程。

以上是 runtime 在賦值與取值做的整個流程毕贼,這些資料我也是在網(wǎng)上找的自己對其流程也知之甚少温赔,希望與之共進(jìn)步。

總結(jié)

知其然鬼癣,知其所以然玉锌。做技術(shù)需要有一絲不茍的精神沟蔑,曾同事說過這么一段話:不要以為將別人的東西粘貼復(fù)制過來混萝,改改名字就變成了自己的東西了妖混。這句話也令我反思,是啊章郁,現(xiàn)在搞技術(shù)都太浮躁枉氮,無論 demo 是如何實現(xiàn)的志衍,用到了哪些知識從不關(guān)心,符合自己需求的直接粘貼復(fù)制過來聊替,我想這種做法就違背了寫 demo 人的根本意圖了楼肪。仰望星空的同時一定要腳踏實地,我將與你一路同行惹悄。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末春叫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子泣港,更是在濱河造成了極大的恐慌暂殖,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件爷速,死亡現(xiàn)場離奇詭異央星,居然都是意外死亡霞怀,警方通過查閱死者的電腦和手機(jī)惫东,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來毙石,“玉大人廉沮,你說我怎么就攤上這事⌒炀兀” “怎么了滞时?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長滤灯。 經(jīng)常有香客問我坪稽,道長,這世上最難降的妖魔是什么鳞骤? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任窒百,我火速辦了婚禮,結(jié)果婚禮上豫尽,老公的妹妹穿的比我還像新娘篙梢。我一直安慰自己,他們只是感情好美旧,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布渤滞。 她就那樣靜靜地躺著,像睡著了一般榴嗅。 火紅的嫁衣襯著肌膚如雪妄呕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天嗽测,我揣著相機(jī)與錄音绪励,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛优炬,可吹牛的內(nèi)容都是我干的颁井。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼蠢护,長吁一口氣:“原來是場噩夢啊……” “哼雅宾!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起葵硕,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤眉抬,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后懈凹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蜀变,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年介评,在試婚紗的時候發(fā)現(xiàn)自己被綠了库北。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡们陆,死狀恐怖寒瓦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情坪仇,我是刑警寧澤杂腰,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站椅文,受9級特大地震影響喂很,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜皆刺,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一少辣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧芹橡,春花似錦毒坛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至腿箩,卻和暖如春豪直,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背珠移。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工弓乙, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留末融,地道東北人。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓暇韧,卻偏偏與公主長得像勾习,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子懈玻,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

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

  • 概述在iOS開發(fā)中UITableView可以說是使用最廣泛的控件巧婶,我們平時使用的軟件中到處都可以看到它的影子,類似...
    liudhkk閱讀 9,003評論 3 38
  • 1.badgeVaule氣泡提示 2.git終端命令方法> pwd查看全部 >cd>ls >之后桌面找到文件夾內(nèi)容...
    i得深刻方得S閱讀 4,640評論 1 9
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,129評論 30 470
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理涂乌,服務(wù)發(fā)現(xiàn)艺栈,斷路器,智...
    卡卡羅2017閱讀 134,628評論 18 139
  • 何其有幸,在人生最美的年華罚勾,能與你傾心相遇毅人。人生蒼茫幾十載,需經(jīng)山水幾千重荧库。而我堰塌,卻能夠在花開的年紀(jì)赵刑,得你傾慕眷顧...
    幸運小王子閱讀 598評論 0 3