iOS Crash

代碼下載

iOS Crash 殺手排名

殺手 NO.1

NSInvalidArgumentException 異常

出現(xiàn)這個crash的原因有很多政溃,選取了崩潰次數(shù)較多的crash矿酵。

crash 日志1-1

-[__NSPlaceholderDictionary initWithObjects:forKeys:count:]:
 attempt to insert nil object from objects[3]

crash日志拿到了,怎么復(fù)現(xiàn)該現(xiàn)象呢?我們看到initWithObjects:forKeys:count:浩村,猜測一下應(yīng)該是NSDictionary初始化時的問題证舟,在看后面的提示attempt to insert nil object,此時就可以做一個猜測争舞,應(yīng)該是NSDictionary初始化時插入nil對象造成的異常。下面我們寫一段代碼來驗證一下:

NSString *password = nil;
NSDictionary *dict = @{
                       @"userName": @"bruce",
                       @"password": password
                       };
NSLog(@"dict is : %@", dict);

運行過后澈灼,崩潰信息如下:

2017-01-23 23:08:15.056 CrashDemo[8592:599699] *** Terminating app due 
to uncaught exception 'NSInvalidArgumentException', reason: '***
 -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert
 nil object from objects[1]'

上面的崩潰信息證明了我們的猜測竞川。從崩潰日志記錄中,查詢到該問題的崩潰記錄有33條(總崩潰記錄304條)叁熔,占10.85%委乌,崩潰率比較高。為什么會出現(xiàn)這種現(xiàn)象呢荣回?如何解決這樣的crash呢遭贸?

崩潰率高的原因是因為自己的框架中采用了去model化的設(shè)計思想,不會把后臺返回的數(shù)據(jù)轉(zhuǎn)換成model驹马,而是通過一個reformer機制轉(zhuǎn)換成NSDictionary形式革砸,提供給目標(biāo)對象使用,在轉(zhuǎn)換成NSDictionary的過程中糯累,后臺返回的數(shù)據(jù)有時可能為空算利,就會造成插入nil對象,從而導(dǎo)致crash泳姐。

有3種方案可以解決該問題效拭,如下:

方案一:后臺在返回數(shù)據(jù)的時候進(jìn)行校驗,對空值進(jìn)行處理胖秒。但是在項目中有些空值是有特殊的用途缎患,此種方案不可行。

方案二:在轉(zhuǎn)換成NSDictionary的時候阎肝,對后臺返回的數(shù)據(jù)進(jìn)行校驗挤渔,把空值轉(zhuǎn)換成NSNull對象。方案可行风题,但是需要對現(xiàn)有代碼做大的改動判导,每次轉(zhuǎn)換的時候都需要進(jìn)行校驗嫉父,太麻煩。業(yè)務(wù)高速發(fā)展時期眼刃,這樣做成本太高绕辖。

方案三:有沒有一種無須改動現(xiàn)有代碼又能解決該問題呢?答案是有的擂红,可以利用Objective-C的runtime來解決該問題仪际。

NSDictionary插入nil對象會造成崩潰,但是插入NSNull對象是不會造成崩潰的昵骤,只要利用runtime的Swizzle Method把nil對象給轉(zhuǎn)換成NSNull對象就可以把該問題給解決了树碱。創(chuàng)建一個NSDictionary的類別,利用runtime的Swizzle Method來替換系統(tǒng)的方法变秦。源碼實現(xiàn)可以參考Glow團隊封裝的NSDictionary+NilSafe(Github上可下載到), 全部源碼會在文章末尾提供赴恨,現(xiàn)截取其中的部分代碼如下:

- (void)gl_setObject:(id)anObject forKey:(id<NSCopying>)aKey {
    if (!aKey) {
        return;
    }
    if (!anObject) {
        anObject = [NSNull null];
    }
    [self gl_setObject:anObject forKey:aKey];
}

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = NSClassFromString(@"__NSDictionaryM");
        [class gl_swizzleMethod:@selector(setObject:forKey:) withMethod:@selector(gl_setObject:forKey:)];
        [class gl_swizzleMethod:@selector(setObject:forKeyedSubscript:) withMethod:@selector(gl_setObject:forKeyedSubscript:)];
    });
}

crash 日志1-2

2017-01-25 11:33:17.541 CrashDemo[4025:252254] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil'

通過日志信息,可以把崩潰問題定位到參數(shù)為nil的情況伴栓,在看了下堆棧的日志信息,把問題定位到了NSJSONSerialization序列化的時候雨饺,傳入data為nil钳垮,造成的崩潰。為了驗證是不是該問題额港,我寫了一段代碼做了下驗證:

NSData *data = nil;
NSError *error;
NSDictionary *orginDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
NSLog(@"originDict is : %@", orginDict);

這個問題比較好解決饺窿,在序列化的時候,統(tǒng)一加入判斷移斩,判斷data是不是nil即可

crash 日志1-3

unrecognized selector sent to instance 0x15d23910

造成這條崩潰的原因肚医,想必大家都比較熟悉了,就是一個類調(diào)用了一個不存在的方法向瓷,造成的崩潰肠套。解決這樣的問題,可以在寫一個方法的時候猖任,判斷一下其類的類型你稚,不符合類型的不讓其調(diào)用,也可以使用runtime對常見的方法調(diào)用做一下錯誤兼容朱躺。比如我這邊經(jīng)常會出現(xiàn)這樣的崩潰

-[__NSCFConstantString objectForKeyedSubscript:]: unrecognized selector sent to instance 0x1741af420
-[NSNull length]: unrecognized selector sent to instance 0x1b21e6ef8    
-[__NSCFConstantString objectForKeyedSubscript:]: unrecognized selector sent to instance
-[__NSDictionaryI length]: unrecognized selector sent to instance 0x174264500

當(dāng)這些對象調(diào)用這幾個不存在的方法的時候刁赖,替換成自己定義的一個方法,對它們做一下錯誤兼容长搀,使應(yīng)用不會崩潰∮畛冢現(xiàn)截取部分代碼實現(xiàn),全部源碼會在文章末尾提供源请。

@implementation NSString (NSRangeException)

+ (void)load{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        @autoreleasepool {
            [objc_getClass("__NSCFConstantString") swizzleMethod:@selector(objectForKeyedSubscript:) swizzledSelector:@selector(replace_objectForKeyedSubscript:)];
        }
    });
}

- (id)replace_objectForKeyedSubscript:(NSString *)key {
    return nil;
}

@end

小結(jié)一下枪芒,造成NSInvalidArgumentException異常大概有以下原因:
NSDictionary插入nil的對象彻况。NSMutableDictionary也是同樣的道理。
NSJSONSerialization序列化的時候病苗,傳入data為nil疗垛。
an unrecognized selector 無法識別的方法
NSInvalidArgumentException的崩潰記錄有149條(總崩潰記錄304條),占49.01%硫朦,稱霸Crash界贷腕,殺手排名第一。

殺手 NO.2:SIGSEGV 異常

SIGSEGV是當(dāng)SEGV發(fā)生的時候咬展,讓代碼終止的標(biāo)識泽裳。當(dāng)去訪問沒有被開辟的內(nèi)存或者已經(jīng)被釋放的內(nèi)存時,就會發(fā)生這樣的異常破婆。另外涮总,在低內(nèi)存的時候,也可能會產(chǎn)生這樣的異常祷舀。
對于這樣的異常瀑梗,我們可以使用兩種方式來解決,一種方式使用Xcode自帶的內(nèi)存分析工具(Leaks)裳扯,一種是使用facebook提供的自動化工具來監(jiān)測內(nèi)存泄漏問題抛丽,如:

FBRetainCycleDetector、FBAllocationTracker饰豺、FBMemoryProfiler

例子1:
dataOut = malloc(dataOutAvailable * sizeof(uint8_t));
這是使用Xcode自帶的Leaks工具檢測到的內(nèi)存泄漏亿鲜,通過代碼我們看出這是一個C語言使用malloc函數(shù)分配了一塊內(nèi)存地址,但是在不使用的時候卻忘記了釋放其內(nèi)存地址冤吨,這樣就造成了內(nèi)存泄漏蒿柳,應(yīng)該在其不使用的時候加上如下代碼:
free(dataOut);
另外,通過這個例子我們也要特別注意漩蟆,在使用C語言對象的時候垒探,一定要記得在不使用的時候給釋放掉,ARC并不能釋放掉這塊內(nèi)存爆安。
例子2:
Can't add self as subview crash
造成這個崩潰的原因叛复,一種原因是在push或pop一個視圖的時候,并且設(shè)置了animated:YES扔仓,如果此時動畫(animated)還沒有完成褐奥,這個時候,你在去push或pop另外一個視圖的時候翘簇,就會造成該異常撬码。 也有其他原因可以造成這個崩潰,比如:
[self.view addSubview:self.view];
復(fù)現(xiàn)這個現(xiàn)象版保,我寫了一個下面的代碼測試呜笑,如下:

- (IBAction)btnAction:(id)sender {
    UIViewController *test01 = [[UIViewController alloc] init];
    [self.navigationController pushViewController:test01 animated:YES];
    [self.navigationController pushViewController:test01 animated:YES];
}

解決該異常最簡單的方式是把animated設(shè)置為NO夫否,但是很不友好,把系統(tǒng)自帶的動畫效果給去掉了叫胁。另外一種友好的方式就是通過runtime來進(jìn)行實現(xiàn)了凰慈,通過安全的方式,確保當(dāng)有控制器正在進(jìn)行入椡斩欤或出棧時微谓,沒有其他入棧或出棧操作输钩。具體源碼如下:


#import <Foundation/Foundation.h>

@interface NSObject (Swizzling)

+ (void)swizzleMethod:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector;

@end


#import "NSObject+Swizzling.h"
#import <objc/runtime.h>

@implementation NSObject (Swizzling)
//交互方法的實現(xiàn)
+ (void)swizzleMethod:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector {
    Class class = [self class];
    //原有方法
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    //替換原有方法的新方法
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
    //先嘗試給源SEL添加IMP豺型,這里是為了避免源SEL沒有實現(xiàn)IMP的情況
    BOOL didAddMethod = class_addMethod(class,originalSelector,
                                        method_getImplementation(swizzledMethod),
                                        method_getTypeEncoding(swizzledMethod));
    if (didAddMethod) {
        //添加成功:說明源SEL沒有實現(xiàn)IMP,將源SEL的IMP替換到交換SEL的IMP
        class_replaceMethod(class,swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
    } else {
        //添加失斅蚰恕:說明源SEL已經(jīng)有IMP姻氨,直接將兩個SEL的IMP交換即可
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

@end

下面代碼中引用的 + (void)swizzleMethod:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector;方法便是上面的NSObject的分類中新增的方法

#import <UIKit/UIKit.h>

@interface UINavigationController (Consistent)

@end


#import "UINavigationController+Consistent.h"
#import <objc/runtime.h>
/// This char is used to add storage for the isPushingViewController property.
static char const * const ObjectTagKey = "ObjectTag";

@interface UINavigationController () <UINavigationControllerDelegate>

@property (readwrite,getter = isViewTransitionInProgress) BOOL viewTransitionInProgress;

@end

@implementation UINavigationController (Consistent)

// 相當(dāng)于為分類添加屬性viewTransitionInProgress的set賦值方法
- (void)setViewTransitionInProgress:(BOOL)property {
    NSNumber *number = [NSNumber numberWithBool:property];
    // 相當(dāng)于賦值,為key ObjectTagKey 賦值一個value即number,因為key是固定的,因此下面的取值是可行的
    objc_setAssociatedObject(self, ObjectTagKey, number , OBJC_ASSOCIATION_RETAIN);
}

// 相當(dāng)于為分類添加屬性viewTransitionInProgress的get取值方法
- (BOOL)isViewTransitionInProgress {

    // 相當(dāng)于從字典的key ObjectTagKey 中獲得一個值,只不過這個字典又沒有顯性的表現(xiàn)出來
    NSNumber *number = objc_getAssociatedObject(self, ObjectTagKey);
    return [number boolValue];
}


+ (void)load {
    //-- Exchange the original implementation with our custom one.
    method_exchangeImplementations(class_getInstanceMethod(self, @selector(pushViewController:animated:)), class_getInstanceMethod(self, @selector(safePushViewController:animated:)));
}

- (void)safePushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    self.delegate = self;
    //-- If we are already pushing a view controller, we dont push another one.
    if (self.isViewTransitionInProgress == NO) {
        //-- This is not a recursion, due to method swizzling the call below calls the original  method.
        [self safePushViewController:viewController animated:animated];
        if (animated) {
            self.viewTransitionInProgress = YES;
        }
    }
}

SIGSEGV的崩潰記錄有57條(總共304條崩潰記錄),占18.75%剪验。在Crash界排名第二肴焊。

殺手 NO.3:NSRangeException 異常

造成這個異常,就是越界異常了功戚,在iOS中我們經(jīng)常碰到的越界異常有兩種抖韩,一種是數(shù)組越界,一種字符串截取越界疫铜,我們通過crash日志來具體分析一下。
crash 日志3-1

-[__NSArrayM objectAtIndex:]: index 1 beyond bounds for empty array
-[__NSCFConstantString substringToIndex:]: Index 10 out of bounds; string length 0

通過日志可以很明顯的知道問題双谆,就是越界造成的壳咕,復(fù)現(xiàn)該現(xiàn)象也比較簡單,在此就略過了顽馋。怎么解決呢谓厘?
方案一:
在對數(shù)組取數(shù)據(jù)的時候,要判斷一下數(shù)組的長度大于取的index寸谜,這個要在平時寫代碼的時候給規(guī)范起來竟稳。同樣在對字符串進(jìn)行截取的時候,也需要做類似的判斷熊痴。但現(xiàn)實的情況是他爸,有時我們會忘了寫這樣的邏輯判斷,就會有潛在的崩潰問題果善。如何做一下統(tǒng)一的判斷呢诊笤?即使開發(fā)人員忘了寫這樣的邏輯判斷也不會造成崩潰,從框架層面來杜絕這類的崩潰巾陕,方案二給出了答案讨跟。
方案二:
利用runtime的Swizzle Method特性纪他,可以實現(xiàn)從框架層面杜絕這類的崩潰問題,這樣做的好處有兩點:
1.開發(fā)人員忘了寫判斷越界的邏輯晾匠,也不會造成app的崩潰茶袒,對開發(fā)人員來說是透明的。
2.不需要修改現(xiàn)有的代碼凉馆,對現(xiàn)有代碼的侵入性降低到最低薪寓,不需要添加大量重復(fù)的邏輯判斷代碼。
全部源碼會在文章末尾提供句喜,現(xiàn)截取部分代碼實現(xiàn):

@implementation NSArray (NSRangeException)

+ (void)load{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        @autoreleasepool {
            [objc_getClass("__NSArray0") swizzleMethod:@selector(objectAtIndex:) swizzledSelector:@selector(emptyObjectIndex:)];
            [objc_getClass("__NSArrayI") swizzleMethod:@selector(objectAtIndex:) swizzledSelector:@selector(arrObjectIndex:)];
            [objc_getClass("__NSArrayM") swizzleMethod:@selector(objectAtIndex:) swizzledSelector:@selector(mutableObjectIndex:)];
            [objc_getClass("__NSArrayM") swizzleMethod:@selector(insertObject:atIndex:) swizzledSelector:@selector(mutableInsertObject:atIndex:)];
        }
    });
}

- (id)emptyObjectIndex:(NSInteger)index{
    return nil;
}

- (id)arrObjectIndex:(NSInteger)index{
    if (index >= self.count || index < 0) {
        return nil;
    }
    return [self arrObjectIndex:index];
}

- (id)mutableObjectIndex:(NSInteger)index{
    if (index >= self.count || index < 0) {
        return nil;
    }
    return [self mutableObjectIndex:index];
}

- (void)mutableInsertObject:(id)object atIndex:(NSUInteger)index{
    if (object) {
        [self mutableInsertObject:object atIndex:index];
    }
}

@end

**越界的崩潰記錄有46條(總共崩潰記錄是304條)预愤,占15.13%,在crash界殺手排名第三咳胃。
**

殺手 NO.4:SIGPIPE 異常

先解釋一下什么是SIGPIPE異常植康,通俗一點的描述是這樣的:對一個端已經(jīng)關(guān)閉的socket調(diào)用兩次write,第二次write將會產(chǎn)生SIGPIPE信號展懈,該信號默認(rèn)結(jié)束進(jìn)程销睁。
那如何解決該問題呢?對SIGPIPE信號可以進(jìn)行捕獲存崖,也可將其忽略冻记,對于iOS系統(tǒng)來說,只需要把下面這段代碼放在.pch文件中即可来惧。

// 僅在 IOS 系統(tǒng)上支持 SO_NOSIGPIPE
#if defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL)
    // We do not want SIGPIPE if writing to socket.
    const int value = 1;
    setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(int));
#endif

SIGPIPE的崩潰記錄有11條(總共304條崩潰記錄)冗栗,占3.61%。在Crash界排名第四

先解釋一下什么是SIGPIPE異常供搀,通俗一點的描述是這樣的:對一個端已經(jīng)關(guān)閉的socket調(diào)用兩次write隅居,第二次write將會產(chǎn)生SIGPIPE信號,該信號默認(rèn)結(jié)束進(jìn)程葛虐。
那如何解決該問題呢胎源?對SIGPIPE信號可以進(jìn)行捕獲,也可將其忽略屿脐,對于iOS系統(tǒng)來說涕蚤,只需要把下面這段代碼放在.pch文件中即可。

// 僅在 IOS 系統(tǒng)上支持 SO_NOSIGPIPE
#if defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL)
    // We do not want SIGPIPE if writing to socket.
    const int value = 1;
    setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(int));
#endif

SIGPIPE的崩潰記錄有11條(總共304條崩潰記錄)的诵,占3.61%万栅。在Crash界排名第四。

殺手 NO.5:SIGABRT 異常

這是一個讓程序終止的標(biāo)識西疤,會在斷言申钩、app內(nèi)部、操作系統(tǒng)用終止方法拋出瘪阁。通常發(fā)生在異步執(zhí)行系統(tǒng)方法的時候撒遣。如CoreData邮偎、NSUserDefaults等,還有一些其他的系統(tǒng)多線程操作义黎。
注意:這并不一定意味著是系統(tǒng)代碼存在bug禾进,代碼僅僅是成了無效狀態(tài),或者異常狀態(tài)廉涕。
SIGABRT崩潰記錄9條(總共304條崩潰記錄)泻云,占2.96%。Crash界排名第五狐蜕。

殺手總結(jié)
前面5大crash殺手宠纯,占了89.46%的崩潰率,解決了這5大crash殺手层释,基本上你的app就很健壯了婆瓜,剩下的崩潰問題就需要具體問題具體分析了。

http://zhijianshusheng.github.io/2016/07/11/%E6%8C%89%E5%91%A8%E5%88%86%E7%B1%BB/20160711-0718/%E5%AF%BC%E8%87%B4iOS%E5%B4%A9%E6%BA%83%E7%9A%84%E6%9C%80%E5%B8%B8%E8%A7%815%E5%A4%A7%E5%85%83%E5%87%B6/
https://code.facebook.com/posts/583946315094347/automatic-memory-leak-detection-on-ios/ http://tech.glowing.com/cn/how-we-made-nsdictionary-nil-safe/
http://stackoverflow.com/questions/19560198/ios-app-error-cant-add-self-as-subview https://my.oschina.net/moooofly/blog/474604
http://devma.cn/blog/2016/11/10/ios-beng-kui-crash-jie-xi/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贡羔,一起剝皮案震驚了整個濱河市廉白,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌乖寒,老刑警劉巖猴蹂,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異楣嘁,居然都是意外死亡磅轻,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門逐虚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瓢省,“玉大人,你說我怎么就攤上這事痊班。” “怎么了摹量?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵涤伐,是天一觀的道長。 經(jīng)常有香客問我缨称,道長凝果,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任睦尽,我火速辦了婚禮器净,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘当凡。我一直安慰自己山害,他們只是感情好纠俭,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著浪慌,像睡著了一般冤荆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上权纤,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天钓简,我揣著相機與錄音,去河邊找鬼汹想。 笑死外邓,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的古掏。 我是一名探鬼主播损话,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼冗茸!你這毒婦竟也來了席镀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤夏漱,失蹤者是張志新(化名)和其女友劉穎豪诲,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挂绰,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡屎篱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了葵蒂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片交播。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖践付,靈堂內(nèi)的尸體忽然破棺而出秦士,到底是詐尸還是另有隱情,我是刑警寧澤永高,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布隧土,位于F島的核電站,受9級特大地震影響命爬,放射性物質(zhì)發(fā)生泄漏曹傀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一饲宛、第九天 我趴在偏房一處隱蔽的房頂上張望皆愉。 院中可真熱鬧,春花似錦、人聲如沸幕庐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽翔脱。三九已至奴拦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間届吁,已是汗流浹背错妖。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留疚沐,地道東北人暂氯。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像亮蛔,于是被迫代替她去往敵國和親痴施。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

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

  • [這是第14篇] 序: iOS Crash問題是iOS開發(fā)中難以忽視的存在究流,本文就捕獲iOS Crash辣吃、Cras...
    南華coder閱讀 9,883評論 21 116
  • 本文就捕獲iOS Crash、Crash日志組成芬探、Crash日志符號化神得、異常信息解讀、常見的Crash五部分介紹偷仿。...
    xukuangbo_閱讀 1,581評論 0 0
  • 2017-10-12酝静,星期四节榜,晴,今天女兒放學(xué)回家我在做飯别智,給孩子們炒了愛吃的米粉宗苍,熬了玉米粥,炒了個小白菜豆腐薄榛,...
    文慧成方媽媽閱讀 221評論 0 0
  • 各種絮絮叨叨 魏:你是不是不會說的也會用普通話代替啊? 沙:對啊讳窟。嗯沒有是因為,嗯蛇数,有些家鄉(xiāng)話不知道怎么說嘛。 魏...
    懷夢草閱讀 140評論 3 1
  • 陽光 在風(fēng)中把光芒揮灑 一行熟悉的腳印 清晰的刻在眼簾 花開時是越,看蜂蝶的飛舞 花兒落了耳舅,凄涼在蔓延 就這樣看著 時...
    喂馬砍柴四海為家閱讀 104評論 0 3