搞透AVPlayerViewController,擺出我想要的姿勢(shì)

有那么一些時(shí)候,我們只需要簡(jiǎn)單的播放一些小視頻雾叭,本地的或者網(wǎng)上的資源悟耘,不需要各種炫酷的效果,不需要自己各種控制织狐,只是想安安靜靜的播放完暂幼,退出!網(wǎng)上各種開源的封裝的AVPlayer的開源庫(kù)移迫,各有千秋旺嬉,但是集成進(jìn)來(lái)有感覺(jué)動(dòng)靜太大了,大把大把的控件和控制代理等等厨埋,頭都大了邪媳!對(duì)于我這種菜逼,慌得一批~~所以我就在系統(tǒng)提供的AVPlayerViewController動(dòng)起了手腳荡陷!


AVPlayerViewController的最簡(jiǎn)單使用

#import "ViewController.h"
#import <AVKit/AVKit.h>

@interface ViewController ()
@property (nonatomic, strong) NSString *videoUrl;
@property (nonatomic, strong)AVPlayerViewController *playerVC;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
//    self.videoUrl =  [[NSBundle mainBundle] pathForResource:@"guideMovie1" ofType:@"mov"];
    self.videoUrl = @"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4";
    /*
     因?yàn)槭?http 的鏈接雨效,所以要去 info.plist里面設(shè)置
     App Transport Security Settings
     Allow Arbitrary Loads  = YES
     */
    self.playerVC = [[AVPlayerViewController alloc] init];
    self.playerVC.player = [AVPlayer playerWithURL:[self.videoUrl hasPrefix:@"http"] ? [NSURL URLWithString:self.videoUrl]:[NSURL fileURLWithPath:self.videoUrl]];
    self.playerVC.view.frame = self.view.bounds;
    self.playerVC.showsPlaybackControls = YES;
//self.playerVC.entersFullScreenWhenPlaybackBegins = YES;//開啟這個(gè)播放的時(shí)候支持(全屏)橫豎屏哦
//self.playerVC.exitsFullScreenWhenPlaybackEnds = YES;//開啟這個(gè)所有 item 播放完畢可以退出全屏
    [self.view addSubview:self.playerVC.view];
    
    if (self.playerVC.readyForDisplay) {
        [self.playerVC.player play];
    }
}
@end

就是這么簡(jiǎn)單,我們就可以播放網(wǎng)絡(luò)或者本地視頻啦废赞,簡(jiǎn)潔大氣上檔次徽龟,還是暗黑風(fēng)格哦,如果項(xiàng)目開啟了屏幕方向唉地,自動(dòng)支持橫豎屏切換据悔,美滋滋!上兩張圖來(lái)占占篇幅哈T稀屠尊!

簡(jiǎn)單播放豎屏界面

簡(jiǎn)單播放橫屏界面

但是,但是耕拷!我們有沒(méi)有發(fā)現(xiàn)讼昆,它沒(méi)有退出按鈕,這叫我如何退出呢骚烧!這怎么難倒我浸赫,加個(gè)導(dǎo)航控制器嵌套,so easy~~這時(shí)候你又會(huì)發(fā)現(xiàn)赃绊,播放界面的按鈕被蓋住了(肯定有人會(huì)說(shuō)既峡,進(jìn)來(lái)的時(shí)候設(shè)置導(dǎo)航欄隱藏就好啦,然后播放完顯示導(dǎo)航欄不就好了碧查。运敢。校仑。)接著往下看


拉伸和音量按鈕被遮擋了

那么我們來(lái)監(jiān)聽(tīng)播放狀態(tài)來(lái)控制導(dǎo)航欄的顯示和隱藏吧!

我們?cè)?code>viewDidload里面增加這個(gè)監(jiān)聽(tīng),這個(gè) block 監(jiān)聽(tīng)方式是我學(xué)習(xí)各位大神寫的一個(gè)分類传惠,不必自己釋放 observer

//添加監(jiān)聽(tīng)播放狀態(tài)
    [self HF_addNotificationForName:AVPlayerItemDidPlayToEndTimeNotification block:^(NSNotification *notification) {
        NSLog(@"我播放結(jié)束了迄沫!");
        [self.navigationController setNavigationBarHidden:NO animated:YES];
    }];
    
    if (self.playerVC.readyForDisplay) {
        [self.playerVC.player play];
    }

viewDidAppear里面隱藏導(dǎo)航欄

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self.navigationController setNavigationBarHidden:YES animated:YES];
}

這樣看起來(lái)蠻不錯(cuò)的,達(dá)到我們預(yù)期效果了卦方,就是進(jìn)去隱藏導(dǎo)航欄羊瘩,播放結(jié)束顯示導(dǎo)航欄!
但是這個(gè)視頻短盼砍,如果是很長(zhǎng)的怎么辦尘吗?等到看完才可以退出么,那就太坑爹了浇坐,有木有睬捶!辣么有沒(méi)有機(jī)制監(jiān)聽(tīng)到AVPlayerViewController點(diǎn)擊播放界面顯示工具欄的時(shí)候一并顯示導(dǎo)航欄呢?這時(shí)候就要借助著名的AOP框架Aspects了!在做這件事之前吗跋,我們先看下AVPlayerViewController的視圖層級(jí)和手勢(shì)數(shù)組了侧戴!
首先看下面一張圖,好好利用視圖層級(jí)分析器跌宛,可以看透很多東西的實(shí)現(xiàn)原理哦酗宋!

視圖層級(jí)和手勢(shì)數(shù)組

而下面這張圖是我們需要監(jiān)聽(tīng)的音量控制的層級(jí)圖
音量控制??的層級(jí)圖

從上圖,我們可以知道單擊和雙擊手勢(shì)是添加到了AVPlayerViewControllerContentView上疆拘,那我們?cè)趺磾r截它做事情呢蜕猫?接下來(lái)看我的:

#import "ViewController.h"
#import <AVKit/AVKit.h>
#import "NSObject+BlockObserver.h"
#import <Aspects/Aspects.h>

@interface ViewController ()
@property (nonatomic, strong) NSString *videoUrl;
@property (nonatomic, strong)AVPlayerViewController *playerVC;

//增加兩個(gè)屬性先
//記錄音量控制的父控件,控制它隱藏顯示的 view
@property (nonatomic, weak)UIView *volumeSuperView;
//記錄我們 hook 的對(duì)象信息
@property (nonatomic, strong)id<AspectToken>hookAVPlaySingleTap;
@end

先增加兩個(gè)屬性哎迄,用來(lái)記錄我們需要操作的 view 和 hook 的對(duì)象信息回右!然后在viewDidload里面增加以下代碼:

   //首先獲取我們的手勢(shì)真正的執(zhí)行類 UIGestureRecognizerTarget
//然后手勢(shì)觸發(fā)的方法 selector 為:_sendActionWithGestureRecognizer:
Class UIGestureRecognizerTarget = NSClassFromString(@"UIGestureRecognizerTarget");
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
    _hookAVPlaySingleTap = [UIGestureRecognizerTarget aspect_hookSelector:@selector(_sendActionWithGestureRecognizer:) withOptions:AspectPositionBefore usingBlock:^(id<AspectInfo>info,UIGestureRecognizer *gest){
        if (gest.numberOfTouches == 1) {
            //AVVolumeButtonControl
            if (!self.volumeSuperView) {
                UIView *view = [gest.view findViewByClassName:@"AVVolumeButtonControl"];
                if (view) {
                    while (view.superview) {
                        view = view.superview;
                        if ([view isKindOfClass:[NSClassFromString(@"AVTouchIgnoringView") class]]) {
                            self.volumeSuperView = view;
                          //  [view addObserver:self forKeyPath:@"hidden" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
                           [view HF_addObserverForKeyPath:@"hidden" block:^(__weak id object, id oldValue, id newValue) {
                                NSLog(@"newValue ==%@",newValue);
                                BOOL isHidden = [(NSNumber *)newValue boolValue];//記得要轉(zhuǎn)換哦,不然沒(méi)效果漱挚!
                                dispatch_async(dispatch_get_main_queue(), ^{
                                    [self.navigationController setNavigationBarHidden:isHidden animated:YES];
                                });
                        }
                    }
                }
            }
        }
        
    } error:nil];
#pragma clang diagnostic pop
   if (self.playerVC.readyForDisplay) {
        [self.playerVC.player play];
    }

其中[gest.view findViewByClassName:@"AVVolumeButtonControl"]方法的實(shí)現(xiàn)如下:

- (UIView *)findViewByClassName:(NSString *)className
{
    UIView *view;
    if ([NSStringFromClass(self.class) isEqualToString:className]) {
        return self;
    } else {
        for (UIView *child in self.subviews) {
            view = [child findViewByClassName:className];
            if (view != nil) break;
        }
    }
    return view;
}

設(shè)置完翔烁,我們需要在 viewDidDisappear里面去釋放我們 hook 的對(duì)象,防止反復(fù)添加 hook 和引用的問(wèn)題!

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    [self.navigationController setNavigationBarHidden:NO animated:YES];
    [self.hookAVPlaySingleTap remove];
}

完事旨涝,我們來(lái)驗(yàn)證一下蹬屹!看看能不能達(dá)到我們的預(yù)期效果,點(diǎn)擊播放界面白华,實(shí)現(xiàn)播放工具欄和導(dǎo)航欄的同步顯示隱藏!我們可以預(yù)覽一下效果:


hidden.gif

當(dāng)然慨默,我能寫出來(lái),就說(shuō)明我驗(yàn)證過(guò)啦弧腥!不過(guò)厦取,在這個(gè)基礎(chǔ)上,我肯定是想做的更自然一點(diǎn)點(diǎn)管搪,更高大上一點(diǎn)點(diǎn)啦虾攻!所以我會(huì)自定義一個(gè)控件添加到播放控制器的 view 上铡买,同一風(fēng)格,做到真正的全屏播放台谢,拋棄導(dǎo)航欄寻狂!因此,我們需要再添加一個(gè)控件屬性

//增加一個(gè)關(guān)閉按鈕
@property (nonatomic, strong) UIControl *closeControl;

//懶加載
- (UIControl *)closeControl
{
    if (!_closeControl) {
        _closeControl = [[UIControl alloc] init];
        [_closeControl addTarget:self action:@selector(dimissSelf) forControlEvents:UIControlEventTouchUpInside];
        _closeControl.backgroundColor = [UIColor colorWithRed:0.14 green:0.14 blue:0.14 alpha:0.8];
        _closeControl.tintColor = [UIColor colorWithWhite:1 alpha:0.55];
        NSBundle *bundle = [NSBundle bundleForClass:[self class]];
        UIImage *normalImage = [UIImage imageNamed:@"closeAV" inBundle:bundle compatibleWithTraitCollection:nil];
        [_closeControl.layer setContents:(id)normalImage.CGImage];
        _closeControl.layer.contentsGravity = kCAGravityCenter;
        _closeControl.layer.cornerRadius = 17;
        _closeControl.layer.masksToBounds = YES;
    }
    return _closeControl;
  
}

- (void)dimissSelf
{
    if (self.navigationController.viewControllers.count >1) {
        [self.navigationController popViewControllerAnimated:YES];
    }
    else
    {
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    
}

然后在viewDidLoad里面修改代碼如下朋沮,主要是注釋掉導(dǎo)航欄顯示和隱藏的代碼:

- (void)viewDidLoad {
    [super viewDidLoad];
//    self.videoUrl =  [[NSBundle mainBundle] pathForResource:@"guideMovie1" ofType:@"mov"];
    self.videoUrl = @"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4";
    /*
     因?yàn)槭?http 的鏈接,所以要去 info.plist里面設(shè)置
     App Transport Security Settings
     Allow Arbitrary Loads  = YES
     */
    self.playerVC = [[AVPlayerViewController alloc] init];
    self.playerVC.player = [AVPlayer playerWithURL:[self.videoUrl hasPrefix:@"http"] ? [NSURL URLWithString:self.videoUrl]:[NSURL fileURLWithPath:self.videoUrl]];
    self.playerVC.view.frame = self.view.bounds;
    self.playerVC.showsPlaybackControls = YES;
    //self.playerVC.entersFullScreenWhenPlaybackBegins = YES;//開啟這個(gè)播放的時(shí)候支持(全屏)橫豎屏哦
    //self.playerVC.exitsFullScreenWhenPlaybackEnds = YES;//開啟這個(gè)所有 item 播放完畢可以退出全屏
    [self.view addSubview:self.playerVC.view];
    
    
    //添加監(jiān)聽(tīng)播放狀態(tài)
    [self HF_addNotificationForName:AVPlayerItemDidPlayToEndTimeNotification block:^(NSNotification *notification) {
        NSLog(@"我播放結(jié)束了缀壤!");
//        [self.navigationController setNavigationBarHidden:NO animated:YES];
    }];
    
    
    Class UIGestureRecognizerTarget = NSClassFromString(@"UIGestureRecognizerTarget");
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
    _hookAVPlaySingleTap = [UIGestureRecognizerTarget aspect_hookSelector:@selector(_sendActionWithGestureRecognizer:) withOptions:AspectPositionBefore usingBlock:^(id<AspectInfo>info,UIGestureRecognizer *gest){
        if (gest.numberOfTouches == 1) {
            //AVVolumeButtonControl
            if (!self.volumeSuperView) {
                UIView *view = [gest.view findViewByClassName:@"AVVolumeButtonControl"];
                if (view) {
                    while (view.superview) {
                        view = view.superview;
                        if ([view isKindOfClass:[NSClassFromString(@"AVTouchIgnoringView") class]]) {
                            self.volumeSuperView = view;
//                            [view addObserver:self forKeyPath:@"hidden" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
                            [view HF_addObserverForKeyPath:@"hidden" block:^(__weak id object, id oldValue, id newValue) {
                                NSLog(@"newValue ==%@",newValue);
                                BOOL isHidden = [(NSNumber *)newValue boolValue];
                                dispatch_async(dispatch_get_main_queue(), ^{
//                                    [self.navigationController setNavigationBarHidden:isHidden animated:YES];
                                    [self.closeControl setHidden:isHidden];
                                });
                        
                            }];
                            break;
                        }
                    }
                }
            }
        }
        
    } error:nil];
#pragma clang diagnostic pop
    //這里必須監(jiān)聽(tīng)到準(zhǔn)備好開始播放了樊拓,才把按鈕添加上去(系統(tǒng)控件的懶加載機(jī)制,我們才能獲取到合適的 view 去添加)塘慕,不然很突兀筋夏!
    [self.playerVC.player HF_addObserverForKeyPath:@"status" block:^(__weak id object, id oldValue, id newValue) {
        AVPlayerStatus status = [newValue integerValue];
        if (status == AVPlayerStatusReadyToPlay) {
            UIView *avTouchIgnoringView = self->_playerVC.view;
            [avTouchIgnoringView addSubview:self.closeControl];
    //這里判斷是否劉海屏,不同機(jī)型的放置位置不一樣图呢!
            BOOL ishairScreen = [self.view isHairScreen];
            CGFloat margin = ishairScreen ?90:69;
            [self.closeControl mas_makeConstraints:^(MASConstraintMaker *make) {
                make.right.mas_equalTo(avTouchIgnoringView).offset(-margin);
                make.top.mas_equalTo(avTouchIgnoringView).offset(ishairScreen ?27:6);
                make.width.mas_equalTo(60);
                make.height.mas_equalTo(47);
            }];
            [avTouchIgnoringView setNeedsLayout];
        }
    }];
    
    if (self.playerVC.readyForDisplay) {
        [self.playerVC.player play];
    }
   
}

//別忘了釋放資源
- (void)dealloc
{
    self.playerVC = nil;
}

來(lái)來(lái)來(lái)条篷,上圖:


close按鈕和原生工具欄同步顯示和隱藏

至此,大功告成了蛤织,不過(guò)同步顯示和隱藏過(guò)程需要大家自己去摸索合適的動(dòng)畫了赴叹,我總是踏不準(zhǔn)點(diǎn)!當(dāng)然指蚜,橫豎屏和強(qiáng)制橫屏的方案我這里也大概提一下吧乞巧,主要思路是監(jiān)聽(tīng)屏幕的旋轉(zhuǎn)通知:

//獲取設(shè)備旋轉(zhuǎn)方向的通知,即使關(guān)閉了自動(dòng)旋轉(zhuǎn),一樣可以監(jiān)測(cè)到設(shè)備的旋轉(zhuǎn)方向
        [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
        //旋轉(zhuǎn)屏幕通知
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(onDeviceOrientationChange:)
                                                     name:UIDeviceOrientationDidChangeNotification
                                                   object:nil
         ];

/**
 *  旋轉(zhuǎn)屏幕通知
 */
- (void)onDeviceOrientationChange:(NSNotification *)notification{
 
    UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
    UIInterfaceOrientation interfaceOrientation = (UIInterfaceOrientation)orientation;
    switch (interfaceOrientation) {
        case UIInterfaceOrientationPortraitUpsideDown:{
   
        }
            break;
        case UIInterfaceOrientationPortrait:
            [self changeOrientation:UIInterfaceOrientationPortrait];
        }
            break;
        case UIInterfaceOrientationLandscapeLeft:
            [self changeOrientation:UIInterfaceOrientationLandscapeLeft];
        }
            break;
        case UIInterfaceOrientationLandscapeRight:{
            [self changeOrientation:UIInterfaceOrientationLandscapeRight];
        }
            break;
        default:
            break;
    }
}

-(void)changeOrientation:(UIInterfaceOrientation)orientation{
    if (orientation == UIInterfaceOrientationPortrait) {
        [self setNeedsStatusBarAppearanceUpdate];
        [self forceOrientationPortrait];

    }else{
        [self setNeedsStatusBarAppearanceUpdate];
        [self forceOrientationLandscape];
    }

    if (@available(iOS 11.0, *)) {
        [self setNeedsUpdateOfHomeIndicatorAutoHidden];
    }
    //刷新
    [UIViewController attemptRotationToDeviceOrientation];
}

//強(qiáng)制橫屏
- (void)forceOrientationLandscape
{
      [[UIApplication sharedApplication].delegate.isForceLandscape = YES;
      [[UIApplication sharedApplication].delegate.isForcePortrait = NO;
      [[UIApplication sharedApplication].delegate  application:[UIApplication sharedApplication] supportedInterfaceOrientationsForWindow:self.view.window];
}

//強(qiáng)制豎屏
- (void)forceOrientationPortrait
{

     [[UIApplication sharedApplication].delegate.isForceLandscape = NO;
     [[UIApplication sharedApplication].delegate.isForcePortrait = YES;
     [[UIApplication sharedApplication].delegate application:[UIApplication sharedApplication] supportedInterfaceOrientationsForWindow:self.view.window];
}

在 AppDelegate.h 里面添加以下屬性

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
//添加旋轉(zhuǎn)需要的屬性
@property (nonatomic, assign) BOOL isForceLandscape;
@property (nonatomic, assign) BOOL isForcePortrait;
@end

在 AppDelegate.m 里面實(shí)現(xiàn)以下方法

-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    if (self.isForceLandscape) {
        return UIInterfaceOrientationMaskLandscape;
    }else if (self.isForcePortrait){
        return UIInterfaceOrientationMaskPortrait;
    }
    return UIInterfaceOrientationMaskPortrait;
}

今天的小菜逼裝完了,總感覺(jué)自己在這個(gè)行業(yè)里瑟瑟發(fā)抖摊鸡,找不到上岸的路绽媒!

demo地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市免猾,隨后出現(xiàn)的幾起案子是辕,更是在濱河造成了極大的恐慌,老刑警劉巖猎提,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件获三,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡忧侧,警方通過(guò)查閱死者的電腦和手機(jī)石窑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蚓炬,“玉大人松逊,你說(shuō)我怎么就攤上這事】舷模” “怎么了经宏?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵犀暑,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我烁兰,道長(zhǎ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
  • 文/蒼蘭香墨 我猛地睜開眼问欠,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼肝匆!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起顺献,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤旗国,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后注整,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體能曾,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有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
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至筋遭,卻和暖如春打颤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背漓滔。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工编饺, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人响驴。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓透且,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親豁鲤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子秽誊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件琳骡、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,033評(píng)論 4 62
  • 做任何事情锅论,都要講求方式方法,這樣我們才能把事情做到完美楣号。
    閆玉蓮閱讀 147評(píng)論 0 0
  • 粗細(xì)對(duì)比不夠強(qiáng)烈最易,提按一直都是問(wèn)題,楷書是炫狱,草書也是的藻懒。繼續(xù)努力加油吧。每次解決一個(gè)問(wèn)題视译,然后再考慮其他的嬉荆。
    余一浳閱讀 438評(píng)論 0 1
  • 輕量級(jí)線程:協(xié)程 在常用的并發(fā)模型中员寇,多進(jìn)程弄慰、多線程、分布式是最普遍的蝶锋,不過(guò)近些年來(lái)逐漸有一些語(yǔ)言以first-c...
    Tenderness4閱讀 6,353評(píng)論 2 10
  • 人生會(huì)有迷茫,人生會(huì)遇彷徨躯舔,迷茫只因選擇驴剔,彷徨會(huì)遭挫折!人生十字路口粥庄,更多的時(shí)候丧失,僅僅需要我們不忘初心,堅(jiān)定信心惜互,...
    沐風(fēng)聽(tīng)雨wj閱讀 562評(píng)論 0 0