iOS 定時(shí)中心及高精度定時(shí)

最近一個(gè)做電商類APP的朋友說哪雕,限時(shí)優(yōu)惠頁面 UITableView 上的 Cell 全部都需要倒計(jì)時(shí)钾麸,然后他的預(yù)想做法呢更振,就是每個(gè)一個(gè) Timer 。喂走。殃饿。聽了好震驚呀,因?yàn)樗麄?APP 除了這里很多地方也需要倒計(jì)時(shí)芋肠,可是卻每個(gè)地方都一個(gè) Timer 乎芳。。帖池。 遂建議封裝個(gè)定時(shí)中心LYTimerHelper奈惑,主要的點(diǎn)其實(shí)就如下:

  1. 間隔Inteval一致的Timer同時(shí)間只存在一個(gè)(其實(shí)根據(jù)業(yè)務(wù)一般也是 1s 倒計(jì)時(shí),所以大部分并不會(huì)創(chuàng)建太多個(gè)Timer
  2. 通過key將執(zhí)行的操作通過block加入對(duì)應(yīng)的Timer睡汹,也可通過key移除
  3. 每次Timer喚醒執(zhí)行所有的block后肴甸,都進(jìn)行判斷是否還存在需要執(zhí)行的block,若是不存在則這個(gè)Timer銷毀囚巴,若是存在則繼續(xù)等待下一次喚醒

所以限時(shí)優(yōu)惠頁面就很簡單了原在,使用 MVVM+RAC 輕松的就能完成,只要將頁面中的商品 model 倒計(jì)時(shí)操作加入定時(shí)中心彤叉,根據(jù)對(duì)應(yīng) model 的倒計(jì)時(shí)變化刷新對(duì)應(yīng) cell 的時(shí)間顯示即可庶柿,別的地方亦是如此

很簡單吧,那就順便聊一聊 iOS 里的定時(shí)有哪些


  • NSTimer

NSTimer是最為常見的一種定時(shí)方式秽浇,根據(jù)文檔可以知道它的使用方式也比較簡單浮庐,文檔也表明 NSTimer 是通過添加到RunLoop中被觸發(fā)進(jìn)行工作的,橋接 CFRunLoopTimerRef

Timers work in conjunction with run loops. Run loops maintain strong references to their timers

self.timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(timerRuning) userInfo:nil repeats:YES];
  // 或者
self.timer = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(timerRuning) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
// 或者 延遲30s開始
NSTimeInterval timeInterval = [self timeIntervalSinceReferenceDate] + 30;
NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:timeInterval];
self.timer = [[NSTimer alloc] initWithFireDate:newDate interval:5 target:self selector:@selector(timerRuning) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];

醬紫其實(shí)就可以進(jìn)行定時(shí)(iOS10 提供了更加便利的 block 方法)

RunLoop 影響

上面的代碼在使用過程中柬焕,會(huì)發(fā)現(xiàn)當(dāng) UITableView 在滾動(dòng)過程中审残,定時(shí)器到了時(shí)間并未觸發(fā)

原因
RunLoop 的幾種 Mode

A run loop mode is a collection of input sources and timers to be monitored and a collection of run loop observers to be notified. Each time you run your run loop, you specify (either explicitly or implicitly) a particular “mode” in which to run. During that pass of the run loop, only sources associated with that mode are monitored and allowed to deliver their events. (Similarly, only observers associated with that mode are notified of the run loop’s progress.) Sources associated with other modes hold on to any new events until subsequent passes through the loop in the appropriate mode

說的就是同一時(shí)候 RunLoop 只運(yùn)行在一種 Mode 上,并且只有這個(gè)Mode相關(guān)聯(lián)的源或定時(shí)器會(huì)被傳遞消息斑举,更多內(nèi)容可以查閱RunLoop
mainRunLoop一般處于 NSDefaultRunLoopMode搅轿,但是在滾動(dòng)或者點(diǎn)擊事件等觸發(fā)時(shí),mainRunLoop切換至 NSEventTrackingRunLoopMode富玷,而上面 timer被加入的正是NSDefaultRunLoopMode(未指明也默認(rèn)加入默認(rèn)模式)璧坟,所以滑動(dòng)時(shí)未觸發(fā)定時(shí)操作没宾。

解決

添加timermainRunLoopNSRunLoopCommonMode中或者子線程中,而這里加入子線程中需要注意的手動(dòng)開啟并運(yùn)行子線程的RunLoop

self.timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(timerRuning) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonMode];

NSRunLoopCommonMode這是一組可配置的常用模式沸柔。將輸入源與此模式相關(guān)聯(lián)也會(huì)將其與組中的每個(gè)模式相關(guān)聯(lián)。對(duì)于Cocoa應(yīng)用程序铲敛,此集合默認(rèn)包括NSDefaultRunLoopMode褐澎,NSPanelRunLoopModeNSEventTrackingRunLoopMode

其它需要注意的點(diǎn)
  1. Nonrepeating Timer運(yùn)行完自行無效,以防再次觸發(fā)伐蒋,但 Repeating Timer需要手動(dòng)調(diào)用
[self.timer invalidate];
self.timer = nil;
  1. NSTimer在運(yùn)行期間會(huì)對(duì)target進(jìn)行持有工三,所以切記在退出前invalidate,否則內(nèi)存泄漏了(別再target的dealloc里調(diào)用先鱼,噗噗)

  2. NSTimer非實(shí)時(shí)性的
    a. 一個(gè)是可能因?yàn)楫?dāng)前RunLoop運(yùn)行的Mode不監(jiān)聽導(dǎo)致未能觸發(fā)
    b. 一個(gè)可能當(dāng)前RunLoop做了耗時(shí)的工作俭正,使得持續(xù)時(shí)間超過了一個(gè)或若干個(gè)NSTimer的觸發(fā)時(shí)間,NSTimer不會(huì)進(jìn)行補(bǔ)償操作焙畔,只是此次循環(huán)檢查定時(shí)器時(shí)觸發(fā)NSTimer掸读,但是不影響后面其它的觸發(fā)時(shí)間,因?yàn)?code>NSTimer根據(jù)一開始計(jì)劃的時(shí)間來觸發(fā)宏多,并不根據(jù)每次被觸發(fā)的實(shí)際時(shí)間點(diǎn)來計(jì)算下一次的觸發(fā)時(shí)間
    c. fire方法立即觸發(fā)時(shí)間儿惫,對(duì)于Nonrepeating Timer運(yùn)行完自行無效,但是跟 b 點(diǎn)一樣伸但,不影響Repeating Timer的預(yù)定周期性觸發(fā)

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
     NSLog(@"timer fired ^_^");
}];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
     NSLog(@"a lot of work begin ^_^");
     NSMutableString *countStr = [[NSMutableString alloc] init];
     for (NSUInteger i = 0; i < 9999999; i++) {
           [countStr appendFormat:@"i_ = %ld ", i];
     }
     NSLog(@"a lot of work end ^_^");
});

如 b 點(diǎn)所說肾请,大量工作耗費(fèi)較長時(shí)間,這中間并未觸發(fā)定時(shí)更胖,同時(shí)工作完成在此次循環(huán)檢查了定時(shí)器觸發(fā)了定時(shí) D铛铁,而 E 的時(shí)間點(diǎn)也依然是按一開始的時(shí)間之后 N * 1s的預(yù)計(jì)觸發(fā),而不是在 D 之后 1s


  • CADisplayLink

CADisplayLink是基于屏幕刷新周期的定時(shí)器却妨,一般 60 frames/s饵逐,同樣也是基于RunLoop,因此也會(huì)碰到因?yàn)檫\(yùn)行在非定時(shí)觸發(fā)的Mode或者工作耗時(shí)導(dǎo)致的延遲(這點(diǎn)跟NSTimer一樣)管呵,這里需要注意的是回調(diào)工作若是當(dāng)前線程大量計(jì)算梳毙,也會(huì)導(dǎo)致下一次的延遲,掉幀卡頓發(fā)生
使用也比較簡單捐下,文檔說的比較清楚

// 1.初始化
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLink:)];
// 2. 設(shè)置 - 2楨回調(diào)一次账锹,這里非時(shí)間,而是以楨為單位
self.displayLink.frameInterval = 2; //iOS10之前
self.displayLink.preferredFramesPerSecond = 30; //iOS10及之后

// 3.加入RunLoop
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
//
// 4.callback
- (void)displayLink:(CADisplayLink *)displayLink {
    ... ...
// 5.時(shí)間累計(jì):每次回調(diào)的間隔時(shí)間
    self.accumulator += displayLink.duration * displayLink.frameInterval; //粗略計(jì)算坷襟,因?yàn)榭赡芘龅酱罅抗ぷ鞯葘?dǎo)致間隔時(shí)間bu zhu
// 或者??
    if (self.timestamp == 0) {
        self.timestamp = displayLink.timestamp;
    }
    CFTimeInterval now = displayLink.timestamp; // 獲取當(dāng)前的時(shí)間戳
    self.accumulator += now - self.timestamp;
    self.timestamp = now;
// 6.預(yù)計(jì)下一次時(shí)間
    NSTimeInterval next = displayLink.targetTimestamp; //iOS10及之后
}
... ...
// 7.暫停
self.displayLink.paused = YES;
// 8.銷毀
[self.displayLink invalidate];
self.displayLink = nil;

CADisplayLink因?yàn)橥狡聊凰⑿骂l率奸柬,屏幕刷新后立即回調(diào),因此很適合跟 UI 相關(guān)的定時(shí)繪制操作婴程,像進(jìn)度條廓奕、FPS等等,這樣就無須進(jìn)行多余運(yùn)算
同樣 CADisplayLink 會(huì)對(duì) target 持有,所以記得進(jìn)行釋放桌粉,以免造成內(nèi)存泄露


  • GCD

Grand Central Dispatch 簡稱 GCD蒸绩,一套低層API,提供了簡單易用并無需直接操作線程居于隊(duì)列的并發(fā)編程铃肯,詳情查閱
GCD 功能非常強(qiáng)大患亿,今天只涉及 Dispatch Sources 中的定時(shí)器

Dispatch Sources 替換了處理系統(tǒng)相關(guān)事件的異步回調(diào)函數(shù)。配置一個(gè)dispatch source押逼,需要指定要監(jiān)測(cè)的事件(DISPATCH_SOURCE_TYPE_TIMER等)步藕、dispatch queue、以及處理事件的代碼(blockC函數(shù))挑格。當(dāng)事件發(fā)生時(shí)咙冗,dispatch source會(huì)提交對(duì)應(yīng)的blockC函數(shù)到指定的dispatch queue執(zhí)行

Dispatch Sources監(jiān)聽系統(tǒng)內(nèi)核對(duì)象并處理,通過系統(tǒng)級(jí)調(diào)用漂彤,會(huì)比NSTimer更精準(zhǔn)一些

// 1. 創(chuàng)建 dispatch source雾消,并指定檢測(cè)事件為定時(shí)
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue("LY_Timer_Queue", 0));
// 2. 設(shè)置定時(shí)器啟動(dòng)時(shí)間,間隔显歧,容差
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC,  0 * NSEC_PER_SEC); 
// 3. 設(shè)置callback
dispatch_source_set_event_handler(timer, ^{
        NSLog(@"timer fired ^_^");
    });
dispatch_source_set_event_handler(timer, ^{
       //取消定時(shí)器時(shí)一些操作
    });
// 4.啟動(dòng)定時(shí)器-剛創(chuàng)建的source處于被掛起狀態(tài)
dispatch_resume(timer);
// 5.暫停定時(shí)器
dispatch_suspend(timer);
// 6.取消定時(shí)器
dispatch_source_cancel(timer);
timer = nil;

覺得每次創(chuàng)建代碼太多仪或,封裝下即可

需要注意的點(diǎn)
  1. 與其他 dispatch objects 一樣,dispatch sources 也是引用計(jì)數(shù)數(shù)據(jù)類型士骤,在 ARC 中無需手動(dòng)調(diào)用 dispatch_release(timer)

  2. dispatch_suspend(timer)timer 掛起范删,若是此時(shí)已經(jīng)在執(zhí)行 block,繼續(xù)完成此次 block拷肌,并不會(huì)立即停止

  3. dispatch source在掛起時(shí)到旦,直接設(shè)置為 nil 或者 其它新源都會(huì)造成crash,需要在activate的狀態(tài)下調(diào)用dispatch_source_cancel(timer)后再重新創(chuàng)建巨缘。

  4. dispatch_source_set_timer中設(shè)置啟動(dòng)時(shí)間添忘,dispatch_time_t可通過兩個(gè)方法生成:dispatch_timedispatch_walltime
    a. dispatch_time創(chuàng)建相對(duì)時(shí)間,基于mach_absolute_time若锁,CPU的時(shí)鐘周期數(shù)ticks搁骑,這個(gè)tricks在每次手機(jī)重啟之后,會(huì)重新開始計(jì)數(shù)又固,而且iPhone鎖屏進(jìn)入休眠之后tick也會(huì)暫停計(jì)數(shù),mach_absolute_time()不會(huì)受系統(tǒng)時(shí)間影響仲器,只受設(shè)備重啟和休眠行為影響。

    b. dispatch_walltime類似創(chuàng)建絕對(duì)時(shí)間仰冠,當(dāng)設(shè)備休眠時(shí)乏冀,時(shí)間依然再走

    所以這兩者的區(qū)別就是,當(dāng)設(shè)備休眠時(shí)洋只,dispatch_time停止運(yùn)行辆沦,dispatch_walltime繼續(xù)運(yùn)行昼捍,所以如果一個(gè)事件處理是在30分鐘之后,運(yùn)行5分鐘后肢扯,設(shè)備休眠20分鐘妒茬,兩個(gè)時(shí)間對(duì)應(yīng)的事件觸發(fā)點(diǎn)如下:

  1. 若是想像 NSTimer 實(shí)現(xiàn) Nonrepeating Timer,則使用 dispatch_after
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
});
  1. dispatch_source 可內(nèi)部持有也可外部持有蔚晨,內(nèi)部持有可在事件處理block中進(jìn)行有條件取消
dispatch_source_set_event_handler(timer, ^{
        NSLog(@"dis timer fired ^_^");
        if (條件滿足) {
            dispatch_source_cancel(timer);
        }
    });
  1. 可以通過dispatch_set_target_queue(timer, queue)更改事件處理的所在隊(duì)列郊闯,修改 dispatch source 是異步操作,所以不會(huì)更改已經(jīng)在執(zhí)行的事件

  2. dispatch_resumedispatch_suspend調(diào)用需一一對(duì)應(yīng)蛛株,重復(fù)調(diào)用dispatch_resume會(huì)crash


  • 高精度定時(shí)

以上的幾種定時(shí)都會(huì)受限于蘋果為了保護(hù)電池和提高性能采用的策略而導(dǎo)致有延遲,像NSTimer會(huì)有50-100毫秒的誤差育拨,若的確需要使用更高精度的定時(shí)器(誤差小于0.5毫秒)谨履,一般在多媒體操作方面有所需要,蘋果官方同樣也提供了方法熬丧,閱讀高精度定時(shí)文檔
高精度定時(shí)用到的比較少笋粟,一般視頻或者音頻相關(guān)數(shù)據(jù)流操作中需要

其實(shí)現(xiàn)原理就是使定時(shí)器的線程優(yōu)先于系統(tǒng)上的其他線程,在無多線程沖突的情況下析蝴,這定時(shí)器的請(qǐng)求會(huì)被優(yōu)先處理害捕,所以不要?jiǎng)?chuàng)建大量的實(shí)時(shí)線程,一旦某個(gè)線程都要被優(yōu)先處理闷畸,結(jié)果就是實(shí)時(shí)線程都失敗了

所以現(xiàn)在實(shí)現(xiàn)高精度定時(shí)有兩種方法:
1.使用Mach Thread API把定時(shí)器所在的線程尝盼,移到高優(yōu)先級(jí)的線程調(diào)度類即the real time scheduling class

#include <mach/mach.h>
#include <mach/mach_time.h>
#include <pthread.h>
 
void move_pthread_to_realtime_scheduling_class(pthread_t pthread)
{
    mach_timebase_info_data_t timebase_info;
    mach_timebase_info(&timebase_info);
 
    const uint64_t NANOS_PER_MSEC = 1000000ULL;
    double clock2abs = ((double)timebase_info.denom / (double)timebase_info.numer) * NANOS_PER_MSEC;
 
    thread_time_constraint_policy_data_t policy;
    policy.period      = 0;
    policy.computation = (uint32_t)(5 * clock2abs); // 5 ms of work
    policy.constraint  = (uint32_t)(10 * clock2abs);
    policy.preemptible = FALSE;
 
    int kr = thread_policy_set(pthread_mach_thread_np(pthread_self()),
                   THREAD_TIME_CONSTRAINT_POLICY,
                   (thread_policy_t)&policy,
                   THREAD_TIME_CONSTRAINT_POLICY_COUNT);
    if (kr != KERN_SUCCESS) {
        mach_error("thread_policy_set:", kr);
        exit(1);
    }
}

2.使用更精確的計(jì)時(shí)API mach_wait_until(),如下代碼使用mach_wait_until()等待10秒

#include <mach/mach.h>
#include <mach/mach_time.h>
 
static const uint64_t NANOS_PER_USEC = 1000ULL;
static const uint64_t NANOS_PER_MILLISEC = 1000ULL * NANOS_PER_USEC;
static const uint64_t NANOS_PER_SEC = 1000ULL * NANOS_PER_MILLISEC;
 
static mach_timebase_info_data_t timebase_info;
 
static uint64_t abs_to_nanos(uint64_t abs) {
    return abs * timebase_info.numer  / timebase_info.denom;
}
 
static uint64_t nanos_to_abs(uint64_t nanos) {
    return nanos * timebase_info.denom / timebase_info.numer;
}
 
void example_mach_wait_until(int argc, const char * argv[])
{
    mach_timebase_info(&timebase_info);
    uint64_t time_to_wait = nanos_to_abs(10ULL * NANOS_PER_SEC);
    uint64_t now = mach_absolute_time();
    mach_wait_until(now + time_to_wait);
}

以上的所有定時(shí)器佑菩,雖然提供方法各不相同盾沫,但它們的內(nèi)核代碼是相同的

  1. NSTimer平時(shí)用的比較多,一般也足夠殿漠,需要注意的就是加入的RunLoopMode 或者若是子線程赴精,需要手動(dòng)啟動(dòng)并運(yùn)行RunLoop;同時(shí)注意使用invalidate手動(dòng)停止定時(shí)绞幌,否則引起內(nèi)存泄漏蕾哟;
  2. 需與顯示更新同步的定時(shí),建議CADisplayLink莲蜘,可以省去多余計(jì)算
  3. GCD定時(shí)精度較NSTimer高谭确,使用時(shí)只需將任務(wù)提交給相應(yīng)隊(duì)列即可,對(duì)文件資源等定期讀寫操作很方便菇夸,使用時(shí)需要??dispatch_resumedispatch_suspend配套琼富,同時(shí)要給 dispatch source設(shè)置新值或者置nil,需先dispatch_source_cancel(timer)
  4. 高精度定時(shí),使用較少庄新,一般多媒體視頻流/音頻流處理相關(guān)需要

好了鞠眉,就寫到這里吧薯鼠,反正吃飯時(shí)間到了。械蹋。出皇。就醬紫

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市哗戈,隨后出現(xiàn)的幾起案子郊艘,更是在濱河造成了極大的恐慌,老刑警劉巖唯咬,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纱注,死亡現(xiàn)場離奇詭異,居然都是意外死亡胆胰,警方通過查閱死者的電腦和手機(jī)狞贱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蜀涨,“玉大人瞎嬉,你說我怎么就攤上這事『窳” “怎么了氧枣?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長别垮。 經(jīng)常有香客問我便监,道長,這世上最難降的妖魔是什么碳想? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任茬贵,我火速辦了婚禮,結(jié)果婚禮上移袍,老公的妹妹穿的比我還像新娘解藻。我一直安慰自己,他們只是感情好葡盗,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布螟左。 她就那樣靜靜地躺著,像睡著了一般觅够。 火紅的嫁衣襯著肌膚如雪胶背。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天喘先,我揣著相機(jī)與錄音钳吟,去河邊找鬼。 笑死窘拯,一個(gè)胖子當(dāng)著我的面吹牛红且,可吹牛的內(nèi)容都是我干的坝茎。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼暇番,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼嗤放!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起壁酬,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤次酌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后舆乔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岳服,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年希俩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了派阱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡斜纪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出文兑,到底是詐尸還是另有隱情盒刚,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布绿贞,位于F島的核電站因块,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏籍铁。R本人自食惡果不足惜涡上,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拒名。 院中可真熱鬧吩愧,春花似錦、人聲如沸增显。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽同云。三九已至糖权,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間炸站,已是汗流浹背星澳。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留旱易,地道東北人禁偎。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓腿堤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親届垫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子释液,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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