iOS開發(fā)技巧系列---使用泛型類來實(shí)現(xiàn)數(shù)據(jù)持久化

以前在用C#開發(fā)程序的時侯,只要用到數(shù)組,必然離不開泛型季二。再配合集合的擴(kuò)展方法和LINQ檩咱,對于集合數(shù)據(jù)的操作真是得心應(yīng)手,非常爽快胯舷。后來我轉(zhuǎn)到iOS開發(fā)刻蚯,學(xué)會了Objective語言。發(fā)現(xiàn)在Objective-C里,一般最常用的數(shù)組容器就是NSArray和字典NSDictionary了桑嘶〈缎冢可惜這兩者都不支持泛型。數(shù)據(jù)都是以NSObject的類型添加進(jìn)來不翩,理論上可以保存保存任何的引用類型兵扬,這就需要讓開發(fā)者來確保所有添加的數(shù)據(jù)類型的一至性。同樣的口蝠,當(dāng)從數(shù)組容器里取值時器钟,需要將其轉(zhuǎn)化成對應(yīng)的Model。有時侯還需要進(jìn)行類型判斷妙蔗。這樣的操作不僅增加了代碼的復(fù)雜性傲霸,也很容易出錯。而Swift作為一門后起之秀眉反,必然添加了對泛型的支持昙啄。彌補(bǔ)了Objective-C對數(shù)組操作的安全性,復(fù)雜性等的不足寸五,而本篇文章向大家介紹了如果來定義一個泛型類梳凛,通過它來作為一種可以永久保存任意數(shù)據(jù)類型的數(shù)據(jù)容器,來實(shí)現(xiàn)iOS的數(shù)據(jù)持久化梳杏。

什么是泛型

為了更直觀一點(diǎn),首先讓我們來看看不支持泛型的Objective-C語言是怎么利用數(shù)據(jù)容器的

    @interface demo:NSObject//自定義對象
    @property (nonatomic,copy) NSString* demoString;
    @end
    @implementation demo

    @end

    NSMutableArray* arr = [NSMutableArray new];
    [arr addObject:[NSNumber numberWithBool:YES]];          //添加Bool類型
    [arr addObject:@"111"];                                 //可以字符串
    demo* dm = [demo new];
    dm.demoString = @"String";
    [arr addObject:dm];                                     //添加自定義對象
    NSLog(@"%@",arr);
    BOOL a = [arr[0] boolValue];                            //需要轉(zhuǎn)成Bool
    NSString* b = arr[1] ;                                  //直接將id類型賦到NSString類型
    demo* dm1 = arr[2];                                     //直接將id賦值給demo類型
    NSLog(@"a:%hhd b:%@.dm:%@",a,b,dm1);                    //可以正確地打印出來
    NSString* dm2 = arr[2];                                 //也可以將本身是demo類型的賦值到String
    NSLog(@"%@",dm2);                                       //不會報(bào)錯.運(yùn)行時dm2本身還是demo類型
    dm2.length;                                             //調(diào)用length方法就會出錯,

    打印結(jié)果:
    2016-03-31 15:29:28.437 DemoObjc[1108:32945] (
    1,
    111,
    "<demo: 0x1001025f0>"
    )
    2016-03-31 15:29:28.438 DemoObjc[1108:32945] a:1 b:111.dm:<demo: 0x1001025f0>
    2016-03-31 15:29:28.438 DemoObjc[1108:32945] <demo: 0x1001025f0>//雖然在代碼階段是NSString類型韧拒,但是運(yùn)行時是demo類型
    2016-03-31 15:29:28.438 DemoObjc[1108:32945] -[demo length]: unrecognized selector sent to instance 0x1001025f0
    2016-03-31 15:29:28.439 DemoObjc[1108:32945] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[demo length]: unrecognized selector sent to instance 0x1001025f0'
    )

從上面的示例代碼可以很清楚地看到,因?yàn)镺bjective-C不支持泛型十性,所以編譯器沒有做任何限制叛溢,可以在NSMutableArray里添加任何引用類型的數(shù)據(jù),這些數(shù)據(jù)都以id類型保存劲适。在取值時也一樣楷掉,默認(rèn)取出來的數(shù)據(jù)都是id類型,需要將其轉(zhuǎn)化成原先保存的類型才行霞势。這些操作都是需要開發(fā)者來確保正確性烹植。如果不小心寫錯了斑鸦,編譯器也不會給出任何提示或者警告,只有在運(yùn)行程序時才能觸發(fā)錯誤草雕。所以很容易出現(xiàn)隱藏的Bug鄙才,同時類型轉(zhuǎn)換也增加了代碼的復(fù)雜性。

而泛型的出現(xiàn)剛好完全解決了上面的問題:

var arrInt = [Int]()    //定義了一個數(shù)據(jù)類型是Int類型的數(shù)組,其實(shí)就是一個只能添加Int類型數(shù)據(jù)的NSMutableArray促绵。
arrInt.append(1)        //添加1
arrInt.append(2)        //添加2
arrInt.append("123")    //添加字符串“123”
//編譯器報(bào)錯,Cannot convert value of type 'String' to expected argument type 'Int'
//不能將String轉(zhuǎn)換成Int
print(arrInt[0].dynamicType)  //取第一個值 嘴纺,打印出類型是Int
let str:String = arrInt[1]    //將第二個值賦值給String
//編譯器報(bào)錯败晴, Cannot convert value of type 'Int' to specified type 'String'
//不能將轉(zhuǎn)Int換成String

從上面的代碼很容易看出,對于數(shù)據(jù)類型是Int的數(shù)組栽渴,只能添加Int類型的數(shù)據(jù)尖坤,其他的數(shù)據(jù)類型編譯器都會報(bào)錯。取值也一樣闲擦,取出來的數(shù)直接就是Int類型了慢味,不需要再轉(zhuǎn)型了。
而且比較方便的是Swift的數(shù)據(jù)容器是是可以直接保存值類型的墅冷,不需要像Objective-C一樣需要將其轉(zhuǎn)成NSNumber了纯路。同樣,你也可以聲明一個類型為String類型的數(shù)組([String])寞忿,
或者自定義類的的泛型數(shù)組驰唬,編譯器都會幫你在編碼時告訴你正確的數(shù)據(jù)類型,防止開發(fā)者添加錯誤的數(shù)據(jù)類型腔彰。

使用泛型的優(yōu)點(diǎn)

使用泛型的優(yōu)點(diǎn)有很多:

  • 泛型提供了一個強(qiáng)類型的編程模型
  • 編譯時的類型檢查減少了運(yùn)行時發(fā)生數(shù)據(jù)類型轉(zhuǎn)換異常的幾率
  • 簡化了代碼叫编,緩解了代碼膨脹。
  • 性能得到了提升霹抛,不需要在運(yùn)行時再做類型檢查搓逾。
  • 代碼的可讀性更好,并且有更好的代碼智能提示杯拐。

其實(shí)在最新的XCode 7.X中霞篡,蘋果也悄悄地加入了Objective-C語言的弱泛型支持,見下面代碼。

    NSMutableArray<NSString *>* arrString  = [NSMutableArray new]; //可以在NSMutableArray后面加上數(shù)據(jù)類型藕施,這樣就聲明了一個泛型的NSMutableArray

    [arrString addObject:[NSNumber numberWithUnsignedInteger:1]]; //這里編譯器會警告你添加了錯誤的數(shù)據(jù)類型寇损,但是不會強(qiáng)制報(bào)錯。

可以在聲明NSMutableArray時添加一個弱泛型約束裳食,之所以是弱泛型矛市,是因?yàn)榫幾g器會幫你檢查數(shù)據(jù)類型是否正確,如果不正確會有一個警告诲祸,但是不會強(qiáng)制報(bào)錯浊吏,代碼還是可以編譯過的而昨。



寫代碼時XCode會自動提示它你應(yīng)該添加什么類型的數(shù)據(jù)



取值也會告訴你里面保存了什么類型的數(shù)據(jù)

如果你把錯誤的數(shù)據(jù)類型存進(jìn)去,編譯器會警告找田,但不是強(qiáng)制報(bào)錯歌憨。

iOS數(shù)據(jù)持久化方案的問題

數(shù)據(jù)存儲在APP開發(fā)中起著至關(guān)重要的作用。相信各位開發(fā)者在開發(fā)過程中都有碰到如下情況:

  • 需要一些全局變量,來記錄APP的一些設(shè)置或者是頻繁變動的數(shù)據(jù)
  • 頁面之間或者各種View之間的傳值,
  • 需要臨時緩存一些數(shù)據(jù)墩衙。

這些數(shù)據(jù)存儲的處理在開發(fā)過程極為常見务嫡,而且有一個共同點(diǎn)就是處理的各種數(shù)據(jù)類型完全不一樣,有時是各種數(shù)字(NSNumber),也有很常用的字符串漆改,當(dāng)然各種數(shù)組或者字典也是不可少的心铃。
所以由此帶來的一個問題就是這些數(shù)據(jù)需要以什么的格式保存,保存后取出來又要如何轉(zhuǎn)化成原先的數(shù)據(jù)類型挫剑,這些都是要手寫代碼去處理去扣。前面已經(jīng)說過,泛型正好是解決此類問題而生樊破。但在這里并不是使用泛型數(shù)據(jù)容器愉棱,而是使用泛型類。那么怎么使用泛型類來寫一個通用的數(shù)據(jù)存儲框架哲戚,可以解決以上問題呢奔滑?

首先iOS的數(shù)據(jù)存儲離不開iOS存儲本身的機(jī)制,也就是那如下幾種:

  • Plist
  • 歸檔&NSUserDefault
  • SQLite3
  • CoreData

關(guān)于這些數(shù)據(jù)持久化的介紹和使用方式網(wǎng)絡(luò)上有很多的文章講解惫恼,在這里我就不詳述了档押。而且目前市面上還有不少對這些數(shù)據(jù)持久化API的封裝開源庫,比如說著名的FMDB祈纯,但是都沒有完全解決上面的問題令宿。我們需要一個輕量級,可以在代碼文件的任何位置讀寫腕窥,支持緩存,臨時存儲(APP退出后數(shù)據(jù)丟失)和數(shù)據(jù)發(fā)生變化時的監(jiān)視粒没,同時不需要做數(shù)據(jù)類型的轉(zhuǎn)換且可以保存任何類型數(shù)據(jù)的數(shù)據(jù)存儲方案。而Swift泛型的出現(xiàn)簇爆,使得這種存儲方案成為可能癞松。

使用泛型類來存儲數(shù)據(jù)

和泛型數(shù)據(jù)容器相比,自定義泛型類用得并不多入蛆∠烊兀可能許多初級開發(fā)者不好理解泛型類,更不明白泛型類有什么作用哨毁。關(guān)于這個枫甲,可以去參考Swift的Array或者是NSDictionry的定義,并且練下手會更好一點(diǎn)。下面我們來定義一個泛型類

public class GrandStore<T> {            //在類名后面加個<T>表示這是一個泛型類
    private var name:String!            //這個變量極為重要想幻,相當(dāng)于是一個Key粱栖,表示這個存儲的名稱。
    private var value:T?                //私有內(nèi)部存儲值脏毯,是個泛型字段
    private var defaultValue:T?         //默認(rèn)值闹究,也是個泛型字段
    private var hasValue:Bool = false   //Bool類型,用來判斷有沒有值
    private var timeout:Int = 0         //緩存時間食店,如果你設(shè)定一個帶緩存的存儲數(shù)據(jù)渣淤,需要設(shè)定這個值
    private var storeLevel:Int = 0      //存儲等級,用來判斷保存在什么地方
    private var isTemp = false          //如果設(shè)為true 吉嫩,那么只是放到內(nèi)存里臨時保存       
    private var timeoutDate:NSDate?     //過期的時間砂代,用于帶緩存的存儲
}

上面就是這個泛型存儲類的全部私有字段。各有什么作用注釋里都有說明率挣,下面上它的兩個構(gòu)造器

   public  init(name:String,defaultValue:T) {    //最常用的構(gòu)造器,適用于任何需要永久保存的數(shù)據(jù)
        self.name = name;
        self.defaultValue = defaultValue;
        storeLevel = self.getStoreLevel()       //獲取存儲級別露戒,
    }
   
 
  public  init(name:String,defaultValue:T,timeout:Int) {  //如果你要保存帶緩存的數(shù)據(jù)椒功,需要調(diào)用這個構(gòu)造器。timeout表示你需要緩存的時間智什,單位是秒
        self.name = name;
        self.defaultValue = defaultValue;
        self.timeout = timeout
        if self.timeout > 0{
            timeoutDate = NSDate(timeIntervalSinceNow: Double(self.timeout))
        }
        else{                                            //如果timeout<=0話动漾,那么就是臨時存儲,只保存的內(nèi)存里面荠锭,APP退出后丟失
            isTemp = true
        }
        storeLevel = self.getStoreLevel()               //獲取存儲級別旱眯,
    }

上面是泛型類的兩個構(gòu)造器彭沼。因?yàn)槠鋮?shù)是T類型硼补,也就是泛型求泰,那么就可以往里在傳任何類型蔫敲。同時這是一個默認(rèn)值脖旱,如果你沒有設(shè)定值的話初茶,那也是可以取出值的蝇率,就是這個默認(rèn)值考润。
后面的構(gòu)造器就是帶緩存有的了拥坛。如果你傳的緩存時間大于0蓬蝶,那么這個時間(秒為單位)就是緩存的時間,如果小于等于0猜惋,那就這是一個臨時存儲丸氛。它不會寫到硬盤里面,只保存在內(nèi)存里著摔。
下面上這個泛型類最核心的屬性缓窜,

    
 public  var Value:T?
 {
     get{
        if isExpire{                                    //判斷有沒有過期
            self.clear()                                //過期了就清空,再將是否有值設(shè)成false
            hasValue = false
        }
        if!hasValue                                     //如果沒有值,也就是說過期了或者內(nèi)存中沒有
        {
            if isTemp{                                  //如果是臨時保存的雹洗,直接將其設(shè)成默認(rèn)值
                if self.value == nil{
                    self.value = defaultValue         
                }
            }
            else{                               
               if !store.hasValue(name){                //判斷存儲倉庫里有沒有保存
                    self.value = defaultValue           //如果沒有保存香罐,就設(shè)成默認(rèn)值再保存,
                    store.setValue(self.value)forkey(name)
               }
               else{
                    self.value = store.setValueForKey(name) as? T//有的話直接取出來
               }
                
            }
            hasValue = true                             //將是否有值設(shè)成true
        }
        return self.value                               //返回取出來的值

    }
    set{
        self.value = newValue
        if !isTemp{
            store.setValue(self.value)forkey(name)      //設(shè)值就比較簡單了时肿,直接保存就行了庇茫、
        }
        hasValue = true
    }
}

這里我用了偽代碼,同時省略了一些功能螃成。因?yàn)樵a比較長也有點(diǎn)復(fù)雜旦签,這里有幾個關(guān)鍵點(diǎn)要說明下

  1. 最上面的isExpire是個計(jì)算屬性,用來判斷保存的數(shù)據(jù)有沒有過期寸宏,如果是永久存在的宁炫,就直接返回false,如果不是氮凝,那么根據(jù)timeoutDate來判斷有沒有過期
    private var isExpire:Bool{
        get{
            if timeoutDate == nil{                          //對于永久保存有羔巢,直接返回false
                return false
            }
            else{
                return NSDate().compare(timeoutDate!) == NSComparisonResult.OrderedDescending   //對于有緩存的,根據(jù)timeoutDate判斷有沒有過期
            }
        }
    }

如果已經(jīng)過期罩阵,那么需要清空數(shù)據(jù)竿秆,再將hasValue設(shè)成false。

  1. 如果hasValue是false稿壁,也就是說內(nèi)存中不存在該值幽钢,那么就需要到存儲倉庫去看了。這里面我省略了一些代碼傅是》搜啵總體思路如下:
    先判斷存儲倉庫有沒有,如果沒有喧笔,就直接設(shè)置成默認(rèn)值帽驯,再保存到存儲倉庫里。
    如果存在书闸,就從存儲倉庫里取出界拦,最后再將hasValue設(shè)置成true。
    在這里存儲倉庫是指另一個對iOS數(shù)據(jù)持久化封裝的庫梗劫,你可以用Github常用的開源庫享甸,也可以自己寫。
  2. 其實(shí)對于取出來的數(shù)據(jù)上需要轉(zhuǎn)換的梳侨,由Object轉(zhuǎn)換成T類型就行了蛉威。
  3. 對于設(shè)值,首先判斷是不是臨時保存的走哺,如果不是蚯嫌,那么需要將其保存到存儲倉庫,最后再將hasValue設(shè)成true就行了。

上面就是這個泛型類最核心的功能的代碼實(shí)現(xiàn)择示。這里面其實(shí)是對最常見的valueForKey和setValueForKey二次封裝束凑,并且再將數(shù)據(jù)再轉(zhuǎn)換成T類型。因?yàn)樵谟脴?gòu)造器實(shí)例化這個類時栅盲,
它就會根據(jù)傳入的默認(rèn)值得知保存的數(shù)據(jù)是什么類型的汪诉。所以便可以正確地轉(zhuǎn)換成原先的類型。

至于這些細(xì)節(jié)實(shí)現(xiàn)代碼谈秫,比如數(shù)據(jù)值變化時的監(jiān)視扒寄,每次設(shè)定值時更新緩存過期的時間,怎么將數(shù)據(jù)保存到存儲倉庫里拟烫,以及清空功能等该编,讀者有興趣可以去看源碼GrandStore。 我在里面是采用歸檔的形式來將保存各種數(shù)據(jù)的硕淑。并且在我做的所有項(xiàng)目里都用了這個庫课竣。不過需要注意的是,因?yàn)镺bjective-C沒有泛型支持置媳,所以目前GrandStore可能不支持Objective-C稠氮。只能用到Swift環(huán)境中。如果覺得不錯半开,請給個Star哦!

使用GrandStore

使用GrandStore十分簡單赃份,可以直接寫在全局變量里面寂拆。所以項(xiàng)目里的任何文件都可以直接訪問。
比如你可以用一個值來記錄APP是不是第一次開啟

let AppFirstLaunch = GrandStore(name: "AppFirstLaunch", defaultValue: true) //默認(rèn)為true,說明App是第一次開啟
//一但app有啟用過抓韩,那么將其設(shè)成false就行了纠永,
AppFirstLaunch.Value = false
//判斷APP是不是第一次啟動
if AppFirstLaunch.Value!{
//第一次啟動,在里面寫一些處理的代碼谒拴。
}

怎么樣尝江,用這個來存儲一些全局的變量可以是說十分的方便,無論是讀取還是寫入英上,都不需要特定的方法炭序,也不需要進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換,直接使用就行苍日。
同樣的惭聂,還可以用它來保存其他的任何類型,比如:

let student = GrandStore(name: "student", defaultValue: Student()) //保存自定義類型
class Student:GrandModel{                                      //這里注意相恃,我讓Student繼承了GrandModel辜纲,因?yàn)樵谖覍懙腉randStroe中,我是用歸檔來保存對象的
    var name:String?                                           
    var id:Int = 0
}
let stu = Student()
stu.name = "張三"
stu.id = 1
student.Value = stu              //新建一個Student對象再賦值給GrandStore
let stu1 = student.Value!       //取出來直接就是Student對象,可以直接操作
stu1.name = "李四"
student.Value = stu1            //修改好的值可以再賦回去實(shí)現(xiàn)永久保存

因?yàn)槲沂怯脷w檔來實(shí)現(xiàn)上面所說的存儲倉庫的耕腾。所以如果我想用GrandStore來保存自定義對象见剩,那么要讓它實(shí)現(xiàn)NSCoding協(xié)議,我在前面寫了一系列的文章打造強(qiáng)大的BaseModel中有實(shí)現(xiàn)自動歸檔的GrandModel扫俺,所以可以在這里直接使用苍苞。
無論是數(shù)組還是字典都毫無壓力

 let arrTest = GrandStore(name: "arrTest", defaultValue: [String]()) //保存數(shù)據(jù)
 let dictTest = GrandStore(name: "dictTest", defaultValue: [String:String]())  //保存字典 
 var demoCache = GrandStore(name: "CacheTest", defaultValue: "", timeout: 10) //10秒緩存時間的一個字符串
  var demoTemp = GrandStore(name: "demoTemp", defaultValue: "temp", timeout: 0)//只保存在內(nèi)存里的一個字符串

更多的使用示例請參考我的Github,上面有鏈接

總結(jié)

Swift泛型的出現(xiàn)彌補(bǔ)了Objective-C沒有泛型的去缺陷,更是帶來了更多現(xiàn)代編程語言諸多的便捷特性牵舵。使用Swift的泛型柒啤,我們有了一個最好的強(qiáng)類型編程模式。在此基礎(chǔ)上畸颅,泛型方法担巩,閉包,高階函數(shù)
等有了更好的用武之地没炒,極大的提升了開發(fā)效率涛癌。我在此建議會Objective-C的開發(fā)者嘗試去學(xué)習(xí)Swift,掌握它送火,你會發(fā)現(xiàn)另一片天地拳话。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市种吸,隨后出現(xiàn)的幾起案子弃衍,更是在濱河造成了極大的恐慌,老刑警劉巖坚俗,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件镜盯,死亡現(xiàn)場離奇詭異,居然都是意外死亡猖败,警方通過查閱死者的電腦和手機(jī)速缆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恩闻,“玉大人艺糜,你說我怎么就攤上這事〈鄙校” “怎么了破停?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長尉剩。 經(jīng)常有香客問我辱挥,道長,這世上最難降的妖魔是什么边涕? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任晤碘,我火速辦了婚禮褂微,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘园爷。我一直安慰自己宠蚂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布童社。 她就那樣靜靜地躺著求厕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪扰楼。 梳的紋絲不亂的頭發(fā)上呀癣,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機(jī)與錄音弦赖,去河邊找鬼项栏。 笑死,一個胖子當(dāng)著我的面吹牛蹬竖,可吹牛的內(nèi)容都是我干的沼沈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼币厕,長吁一口氣:“原來是場噩夢啊……” “哼列另!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起旦装,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤页衙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后阴绢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體店乐,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年旱函,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片描滔。...
    茶點(diǎn)故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡棒妨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出含长,到底是詐尸還是另有隱情券腔,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布拘泞,位于F島的核電站纷纫,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏陪腌。R本人自食惡果不足惜辱魁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一烟瞧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧染簇,春花似錦参滴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至青灼,卻和暖如春暴心,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背杂拨。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工专普, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人扳躬。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓脆诉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親贷币。 傳聞我的和親對象是個殘疾皇子击胜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評論 2 353

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件役纹、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,094評論 4 62
  • 1. 他和她的第一次相遇促脉,是在蘇鎮(zhèn)的那條小河邊辰斋。 那天天氣晴朗,碧空萬里瘸味。初秋的傍晚宫仗,紅色的云霞灑落到小河上面,閃...
    木庭兮閱讀 413評論 5 3
  • 上海之行旁仿,不虛此行藕夫,培訓(xùn)師職業(yè)生涯的指路明燈。 作為新入職的培訓(xùn)師枯冈,迷茫過毅贮,遲疑過,徘徊過尘奏,沮喪過滩褥,甚至想過放棄。...
  • 簡單的數(shù)據(jù)類型Undefined炫加,Null瑰煎,Boolean铺然,Number,String丢间。 檢測基本數(shù)據(jù)類型的typ...
    Random_閱讀 276評論 0 0
  • 戰(zhàn)士通用仍然是百穿銘文探熔,至于藍(lán)色銘文的狩獵和隱匿怎么選擇,還是看大家個人使用習(xí)慣烘挫,到底是喜歡多一點(diǎn)攻速诀艰,還是多一點(diǎn)...
    漁夫哥閱讀 777評論 3 1