iOS開發(fā)之?dāng)?shù)據(jù)的持久化存儲機(jī)制

IOS中數(shù)據(jù)的持久化保存這塊內(nèi)容诬乞,類似于Android中文件的幾種常見的存儲方式赡盘。
對于數(shù)據(jù)的持久化存儲讲仰,ios中一般提供了4種不同的機(jī)制檐什。
1.屬性列表
2.對象歸檔
3.數(shù)據(jù)庫存儲(SQLite3)
4.蘋果公司提供的持久性工具Core Data牵祟。

其實(shí)儲存的形式無非就這么幾種深夯,而我們還必須要關(guān)心的是,這些文件會被放置在那個文件下,然后如何讀取咕晋。
也就是說:IOS上數(shù)據(jù)存儲雹拄,我們要了解的兩點(diǎn),數(shù)據(jù)存儲格式(也就是存儲機(jī)制)掌呜,數(shù)據(jù)存儲位置滓玖。
1》文件如何存儲(如上面4點(diǎn))
2》文件存儲在哪里。
對于數(shù)據(jù)的操作质蕉,其實(shí)我們關(guān)心的是操作的速率势篡。
就好比在Adnroid中偏好存儲,數(shù)據(jù)庫存儲模暗,io存儲一樣禁悠。
我大致問了我們公司新來的ios哥們,他說他們培訓(xùn)機(jī)構(gòu)基本對數(shù)據(jù)操作這塊就講了屬性列表和數(shù)據(jù)庫兑宇,以及普通的文件存儲(比如音視頻圖這些多媒體數(shù)據(jù))绷蹲。
我就只好先看看書了。

一:應(yīng)用文件目錄

首先我們來看了解下ios數(shù)據(jù)存儲位置顾孽,因?yàn)橹挥兄牢恢寐窂轿覀儾拍苋プx取數(shù)據(jù)祝钢,而數(shù)據(jù)的持久化機(jī)制不過是針對操作速率來考慮的,
比如我們大致知道屬性列表(既鍵值對形式)的存儲熟慮應(yīng)該高于數(shù)據(jù)庫高于io文件流存儲若厚。
我們在選擇用何種機(jī)制存儲數(shù)據(jù)拦英,主要也是看數(shù)據(jù)的形式。

一個ios應(yīng)用安裝后大致會有如下文件夾及其對應(yīng)路徑:

在mac上看模擬器中應(yīng)用路徑:

/Users/nono/Library/Application Support/iPhone Simulator/5.1/Applications/2D135859-1E80-4754-B36D-34A53C521DE3

你在finder中的home下可能找不到Library這個目錄测秸,因?yàn)槊菜剖怯安仄饋砹耍ㄎ疫@機(jī)器上是达箍,在終端可以看到)矮男。
最后那一竄的類似序列號的東西就是ios自動給應(yīng)用生成的一組應(yīng)用唯一識別碼最為了應(yīng)用的home目錄名。
其下面就是上圖所示了。
書上對這些文件夾介紹:

Document:應(yīng)用程序?qū)⑵鋽?shù)據(jù)存儲在這個文件夾下崭放,基于NSUserDefaults的首選項(xiàng)的設(shè)置除外卓舵。

簡單理解是蜈垮,基本上我們要操作的一些數(shù)據(jù)都是存儲在這個文件夾下面的

TIPS:這邊提下一點(diǎn)汰寓,對于ios系統(tǒng)這么分配文件夾,是因?yàn)樵谠O(shè)備進(jìn)行同步時(shí)缠俺,ITunes有選擇性的意識來備份文件显晶。

比如我們可以猜到,tmp下的應(yīng)該就不會備份了壹士。
對于Document文件夾目錄路徑的獲取磷雇,API提供了這么一種方法:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
   NSString *docPath = [paths objectAtIndex:0];  

Library:基于NSUserDefault首選項(xiàng)設(shè)置存儲在其下Preferences文件夾中,簡單來說躏救,這個文件夾一般你很少操作到唯笙。

書上對于這部分基本沒介紹。估計(jì)對于初級部分是跳過了。

Tmp:應(yīng)用臨時(shí)存儲文件崩掘,當(dāng)不需要時(shí)尿庐,應(yīng)用負(fù)責(zé)刪除其下的文件數(shù)據(jù)。
該文件也提供了目錄獲取方法:

NSString *tmpDoc = NSTemporaryDirectory();

應(yīng)用程序文件:這個基本沒提到書上呢堰,但是我們大致可以猜測,這就是整個應(yīng)用程序的程序文件夾吧凡泣。

好了枉疼,以上我們大致解決了我們提到的第一個點(diǎn),文件存儲目錄

二:數(shù)據(jù)存儲機(jī)制

1.屬性列表 Write寫入方式

這個其實(shí)我們早見過鞋拟,plist就是骂维,感覺用來存儲鍵值對小數(shù)據(jù)是最合適,因?yàn)樗俾屎芨摺?/p>

這個存儲機(jī)制很簡單贺纲,對于前面我們使用過了在plist文件來讀取數(shù)據(jù)填充一些列表航闺,只不過那會plist文件存儲位置不同,

用的是Mainbundle什么的來返回文件夾猴誊,其實(shí)這邊我也推測潦刃,上面提到有個應(yīng)用程序文件夾,它下面的文件就是這么來讀取的~(反正暫時(shí)不管他)

這邊不過就是改變了存儲位置懈叹,數(shù)據(jù)操作還是一樣的

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
NSString *docPath = [paths objectAtIndex:0];  
NSString *myFile = [docPath stringByAppendingPathComponent:@"my.list"];  
//讀取文件  
NSArray *array = [[NSArray alloc] initWithContentsOfFile:myFile];  
//操作完若修改了數(shù)據(jù)則乖杠,寫入文件  
[array writeToFile:myFile atomically:YES]; 

2.對象歸檔
上面的屬性列表存儲機(jī)制,我們都知道澄成,這個機(jī)制支持NSArray,NSDictionary,NSData,NSString,NSNumber,NSDate 等等

這些對象直接寫入plist文件中胧洒。

那么對于一些復(fù)雜對象,我要保存整個這個對象數(shù)據(jù)呢墨状?

反正我是這么覺得卫漫,這個機(jī)制很像java中的對象整體序列化。當(dāng)然肾砂,這些數(shù)據(jù)在讀取是就需要遵循一種墨守成規(guī)的協(xié)議了列赎。

首先我們定義的對象類,必須實(shí)現(xiàn)NSCoding和NSCopying協(xié)議(額镐确,網(wǎng)上說后面這個不實(shí)現(xiàn)也可以粥谬,我猜是他對象沒有copy操作,因此沒出錯)書本上反正是實(shí)現(xiàn)了這兩個協(xié)議
然后歸檔中用到的操作類
NSKeyedArchiver
這邊我們定義一個對象辫塌,h文件中定義兩屬性漏策,申明要實(shí)現(xiàn)的NSCoding和NSCopying協(xié)議

Person.h

#import <Foundation/Foundation.h>

@interface Person : NSObject <NSCoding>

@property (nonatomic,retain)NSString *gender; // 性別
@property (nonatomic,retain)NSString *name; // 姓名
@property (nonatomic,assign)int age; // 年齡
@end

Person.m

#import "Person.h"

@implementation Person


// 歸檔 實(shí)際上就是將當(dāng)前類的屬性編碼為NSData類型
- (void)encodeWithCoder:(NSCoder *)aCoder{
    
    // 實(shí)際編碼過程,原理就是將name這個屬性的值編碼為NSData類型臼氨,因?yàn)槲覀兘獯a的時(shí)候掺喻,需要重新為該類屬性賦值,所以需要加標(biāo)記,也就是Key感耙。
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeObject:self.gender forKey:@"gender"];
    [aCoder encodeInt:self.age forKey:@"age"];
    NSLog(@"執(zhí)行了歸檔的方法");
}

// 反歸檔  因?yàn)闅w檔的過程中褂乍,我們是將當(dāng)前類轉(zhuǎn)換為NSData類型,并且儲存到了某個文件中即硼,當(dāng)我們從文件中讀取出來數(shù)據(jù)的時(shí)候逃片,基礎(chǔ)類型,例如:NSArray等都有initWithContentsOfFile的方法來初始化只酥,但是復(fù)雜類型沒有類似的方法褥实,只能是反歸檔來完成此事。
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
    
    if (self = [super init]) {
        // 將剛才編碼為NSData類型的屬性裂允,又通過解碼方式變回原來的類型损离,上面編碼過程中,所賦給的key值為何種名稱绝编,底下的解碼得對應(yīng)上僻澎。
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.age = [aDecoder decodeIntForKey:@"age"];
        self.gender = [aDecoder decodeObjectForKey:@"gender"];
         NSLog(@"執(zhí)行了反歸檔的方法");
    }
    return self;
}
@end

RootViewController.m

#import "RootViewController.h"
#import "SandBoxPaths.h"
#import "Person.h"
@interface RootViewController ()

@end

@implementation RootViewController


#pragma mark -------- 歸檔
// 歸檔并存入沙盒中
- (void)archiverAndSaveSandBox{
    // 歸檔實(shí)際上就是將Person對象轉(zhuǎn)換為NSData類型的數(shù)據(jù)
    
    
    Person *person = [[Person alloc]init];
    person.name = @"廈航";
    person.age = 24;
    person.gender = @"女";
    
    //  歸檔的時(shí)候,實(shí)際是將復(fù)雜類對象的屬性一一轉(zhuǎn)換為NSData類型十饥,所以是逐步轉(zhuǎn)換的窟勃,最終需要將每一步轉(zhuǎn)換好的NSData類型組裝為一個完整的NSData,所以我們需要一個可變的NSData來接收它
    NSMutableData *receiveData = [[NSMutableData alloc]init];
    //=========================================================================
    // 歸檔操作需要借助系統(tǒng)的一個歸檔工具類來實(shí)現(xiàn)逗堵,這個類實(shí)際的操作就是將Person對象轉(zhuǎn)換為NSData類型的數(shù)據(jù)拳恋,并賦值給剛才咱們初始化的NSData對象
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:receiveData];
    //=========================================================================
    // 歸檔開始
    [archiver encodeObject:person forKey:@"person"];
    // 需要有一個標(biāo)志,讓我們知道歸檔完成了砸捏,我們的receiveData中有值了 (不然會出錯誤)
    [archiver finishEncoding];
    
    // 已經(jīng)轉(zhuǎn)換完成的谬运,就可以進(jìn)行數(shù)據(jù)持久化了
    NSString *pathString = [[SandBoxPaths documentsPath]stringByAppendingPathComponent:@"person.DA"];
    
    [receiveData writeToFile:pathString atomically:YES];
    NSLog(@"-------%@",pathString);
    
}
#pragma mark ----- 反歸檔
- (void)unArichiver{
    // 反歸檔,實(shí)際上就是將NSData類型轉(zhuǎn)換為復(fù)雜類型對象垦藏,就是本例中的person對象
    
    NSString *pathString = [[SandBoxPaths documentsPath]stringByAppendingPathComponent:@"person.DA"];
    NSData *data = [[NSData alloc]initWithContentsOfFile:pathString];
    // 反歸檔梆暖,反歸檔也需要借助系統(tǒng)的一個反歸檔工具類來實(shí)現(xiàn)
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
    // 開始反歸檔
   Person *person =  [unarchiver decodeObjectForKey:@"person"];
    
    NSLog(@"name-------%@",person.name);
    
}
- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self archiverAndSaveSandBox];
    [self unArichiver];
    
    }
    

三.數(shù)據(jù)庫存儲

1.這里必須先要導(dǎo)入一個系統(tǒng)文件。在xcode7.0之后把后綴改了掂骏,現(xiàn)在叫l(wèi)ibsqlite3.tbd

//里面有操作sqlite數(shù)據(jù)庫的所有函數(shù)轰驳,我們要操作數(shù)據(jù)庫,就需要導(dǎo)入libSqlite3的系統(tǒng)庫 路徑:TARGETS -> Build Phases -> Link Binary with Libraries

導(dǎo)入頭文件

#import <sqlite3.h>  //里面有操作sqlite數(shù)據(jù)庫的所有函數(shù)弟灼,我們要操作數(shù)據(jù)庫级解,就需要導(dǎo)入libSqlite3的系統(tǒng)庫 路徑:TARGETS -> Build Phases -> Link Binary with Libraries
#import "SandBoxPaths.h"
@implementation RootViewController
#pragma mark ------ 打開或者創(chuàng)建數(shù)據(jù)庫
// 打開或者創(chuàng)建數(shù)據(jù)庫
- (sqlite3 *)openOrCreateDB{
    // 首先我們需要一個保存數(shù)據(jù)庫的文件路徑
    NSString *dbPath = [[SandBoxPaths documentsPath]stringByAppendingPathComponent:@"db.sqlite" ];
    // 數(shù)據(jù)庫的句柄
    sqlite3 *sqlite3 = NULL;
    // 如果數(shù)據(jù)庫已經(jīng)存在,此函數(shù)就是打開當(dāng)前數(shù)據(jù)庫文件田绑,如果該數(shù)據(jù)庫文件不存在勤哗,那么此函數(shù)就是創(chuàng)建數(shù)據(jù)庫文件并打開。
    // filename:數(shù)據(jù)庫文件的路徑
    // ppDb: 數(shù)據(jù)庫句柄此變量的指針的指針掩驱。當(dāng)前數(shù)據(jù)庫創(chuàng)建或者打開成功之后芒划,會將地址指針保存在該參數(shù)中冬竟,這樣,此句柄變量就可以通過指針來操作數(shù)據(jù)庫民逼。
    // 由于此函數(shù)為C函數(shù),但是dbPath為OC對象泵殴,所以需要將OC字符串轉(zhuǎn)換為C字符串
    // 此函數(shù)有返回值,sqlite3中對所有的操作拼苍,只要沒有返回?cái)?shù)據(jù)結(jié)果集的笑诅,都會有一個int的返回值,來標(biāo)識此操作是否進(jìn)行成功疮鲫。
   int result =  sqlite3_open(dbPath.UTF8String, &sqlite3);
    
    if (result == SQLITE_OK) {
        
        NSLog(@"數(shù)據(jù)庫打開成功");
        
        return sqlite3;
    }else{
        NSLog(@"數(shù)據(jù)庫打開失敗");
        return NULL;
    }
    
}
#pragma mark ---------- 執(zhí)行無返回結(jié)果集的SQL操作
// 執(zhí)行無返回結(jié)果集的SQL操作
- (BOOL)exeSqlWithSQLString:(NSString *)sqlStr{
    // 打開數(shù)據(jù)庫
    sqlite3 *sqlDB = [self openOrCreateDB];
    // 執(zhí)行SQL的函數(shù)
    // 第一個參數(shù):數(shù)據(jù)庫的句柄吆你,可以理解為就是數(shù)據(jù)庫
    // 第二個參數(shù):所要執(zhí)行的sql語句
    // 第三個參數(shù):執(zhí)行完SQL之后的回調(diào)方法。
    // 第四個參數(shù):回調(diào)方法的第一個參數(shù)
    // 第五個參數(shù):錯誤日志棚点,等同于OC中的NSError,這里是char類型湾蔓。
   int result =  sqlite3_exec(sqlDB, sqlStr.UTF8String, NULL, NULL, NULL);
    if (result == SQLITE_OK) {
        NSLog(@"語句執(zhí)行成功");
        // 關(guān)閉數(shù)據(jù)庫
        sqlite3_close(sqlDB);
        return YES;
    }else{
        NSLog(@"語句執(zhí)行失敗");
        // 關(guān)閉數(shù)據(jù)庫
        sqlite3_close(sqlDB);
        return NO;
    }
}
#pragma mark ----- 查詢數(shù)據(jù)庫
// 查詢數(shù)據(jù)庫
- (NSArray *)queryDBWithSqlString:(NSString *)sqlStr{
    
    
    // 初始化一個可變數(shù)組瘫析,一會用來盛放所有的結(jié)果
    NSMutableArray *resultMutableArray = [[NSMutableArray alloc]init];
    // 打開數(shù)據(jù)庫
    sqlite3 *sqlDB = [self openOrCreateDB];
    // 用來保存記錄的指針對象
    sqlite3_stmt *stament = NULL;
    // 用來檢查SQL的函數(shù),如果SQL語句編譯無問題默责,就將編譯好的SQL保存到stament中
   int result =  sqlite3_prepare(sqlDB, sqlStr.UTF8String, -1, &stament, NULL);
    
    if (result == SQLITE_OK) {
        while (sqlite3_step(stament) == SQLITE_ROW){
            
            // while每執(zhí)行一次贬循,就會有一條新記錄,所以我們每次都需要一個新的字典桃序,也就是初始化好的字典來盛放記錄
            NSMutableDictionary *rowDic = [NSMutableDictionary dictionary];
         // 每執(zhí)行一次step函數(shù)杖虾,都會在stament中保存一條完整的記錄。
            // 取出一條記錄中的某個字段
            // 第二個參數(shù)是指取出第幾列的字段值
            
            int number = sqlite3_column_int(stament, 0);
            [rowDic setObject:[NSNumber numberWithInt:number]forKey:@"number"];
            
        const unsigned char *name = sqlite3_column_text(stament, 1);
            NSString *nameString = [NSString stringWithCString:(const char *)name encoding:NSUTF8StringEncoding];
//            NSString *nameString = [NSString stringWithUTF8String:(const char *)name];
            [rowDic setObject:nameString forKey:@"name"];
            const unsigned char *gender = sqlite3_column_text(stament, 2);
            NSString *genderString = [NSString stringWithCString:(const char *)gender encoding:NSUTF8StringEncoding];
            [rowDic setObject:genderString forKey:@"gender"];
            
            
            //組裝好字典之后媒熊,將該字典放入數(shù)組
            [resultMutableArray addObject:rowDic];
        }
    }
    
    // 關(guān)閉數(shù)據(jù)庫
    sqlite3_close(sqlDB);
    // 釋放stament所持有的資源
    sqlite3_finalize(stament);
    return resultMutableArray;
}

這里封裝了DataBaseHelper單例可以直接拿來使用奇适。

四。Core Data存儲機(jī)制

大致瀏覽下基本感覺就是將對象歸檔搞成了可視化和簡單化芦鳍。

這塊內(nèi)容比較多嚷往。網(wǎng)上資料也挺豐富的。

暫時(shí)不做介紹了柠衅。

總結(jié)下:其實(shí)對于ios數(shù)據(jù)存儲皮仁,最常用和主要要掌握的就是屬性列表和數(shù)據(jù)庫,因?yàn)閮蓚€是出鏡率比較高的菲宴。

其他可能在數(shù)據(jù)存明顯體現(xiàn)出儲優(yōu)勢時(shí)贷祈,我們會去考慮用另外兩種機(jī)制。

基礎(chǔ)的來說喝峦,必須掌握屬性列表和sqlite的操作存儲势誊。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市谣蠢,隨后出現(xiàn)的幾起案子键科,更是在濱河造成了極大的恐慌闻丑,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件勋颖,死亡現(xiàn)場離奇詭異嗦嗡,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)饭玲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進(jìn)店門侥祭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人茄厘,你說我怎么就攤上這事矮冬。” “怎么了次哈?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵胎署,是天一觀的道長。 經(jīng)常有香客問我窑滞,道長琼牧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任哀卫,我火速辦了婚禮巨坊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘此改。我一直安慰自己趾撵,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布共啃。 她就那樣靜靜地躺著占调,像睡著了一般。 火紅的嫁衣襯著肌膚如雪移剪。 梳的紋絲不亂的頭發(fā)上妈候,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天,我揣著相機(jī)與錄音挂滓,去河邊找鬼苦银。 笑死,一個胖子當(dāng)著我的面吹牛赶站,可吹牛的內(nèi)容都是我干的幔虏。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼贝椿,長吁一口氣:“原來是場噩夢啊……” “哼想括!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起烙博,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤瑟蜈,失蹤者是張志新(化名)和其女友劉穎烟逊,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體铺根,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宪躯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了位迂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片访雪。...
    茶點(diǎn)故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖掂林,靈堂內(nèi)的尸體忽然破棺而出臣缀,到底是詐尸還是另有隱情,我是刑警寧澤泻帮,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布精置,位于F島的核電站,受9級特大地震影響锣杂,放射性物質(zhì)發(fā)生泄漏脂倦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一蹲堂、第九天 我趴在偏房一處隱蔽的房頂上張望狼讨。 院中可真熱鬧贝淤,春花似錦柒竞、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至离陶,卻和暖如春稼虎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背招刨。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工霎俩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沉眶。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓打却,卻偏偏與公主長得像,于是被迫代替她去往敵國和親谎倔。 傳聞我的和親對象是個殘疾皇子柳击,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評論 2 351

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

  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 10,934評論 6 13
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)片习,斷路器捌肴,智...
    卡卡羅2017閱讀 134,638評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,864評論 25 707
  • 武漢馬拉松已經(jīng)過去一個多禮拜蹬叭,對于很多人來說42.195公里可能是一個遙不可及的概念名詞。但是人生不曾與跑步相識或...
    嘴角的記憶閱讀 539評論 0 51
  • ?軍讖?曰:柔能制剛,弱能制強(qiáng)试幽。柔者筝蚕,德也;剛者铺坞,賊也起宽。弱者人之所助,強(qiáng)者怨之所攻济榨。柔有所設(shè)坯沪,剛有所施;弱有所用擒滑,...
    luozi閱讀 1,451評論 0 0