內(nèi)功心法-多線程的基本使用

一 ) 為什么使用多線程界阁?

每個(gè)iOS應(yīng)用程序都有個(gè)專門用來更新顯示UI界面、處理用戶的觸摸事件的主線程胖喳,因此不能將其他太耗時(shí)的操作放在主線程中執(zhí)行泡躯,不然會(huì)造成主線程堵塞(出現(xiàn)卡機(jī)現(xiàn)象),帶來極壞的用戶體驗(yàn)丽焊。一般的解決方案就是將那些耗時(shí)的操作放到另外一個(gè)線程中去執(zhí)行较剃,多線程編程是防止主線程堵塞,增加運(yùn)行效率的最佳方法技健。

這里有兩個(gè)概念是進(jìn)程和線程写穴。 進(jìn)程就是負(fù)責(zé)程序運(yùn)行的內(nèi)存分配,而線程就是進(jìn)程中得一個(gè)獨(dú)立的執(zhí)行那個(gè)路徑雌贱。它是程序的執(zhí)行路徑啊送,負(fù)責(zé)程序中代碼的實(shí)際運(yùn)行。這好比進(jìn)程就是火車欣孤,線程就是火車的車廂删掀,沒有火車,車廂也跑不起來當(dāng)然一個(gè)火車也不能只有一個(gè)車廂导街。

二)? ios 中常用的三種多線程是什么披泪?

1? Thread: 這是相對(duì)輕量級(jí)別的,抽象級(jí)別相對(duì)來說比較低搬瑰,但是需要管理線程的生命周期款票,同步以及加鎖,這會(huì)導(dǎo)致一定的性能開銷

2 Operations:? 這個(gè)是基于OC實(shí)現(xiàn)的泽论,以面向?qū)ο蟮姆绞椒庋b了需要執(zhí)行的操作艾少,我們可以不必關(guān)心線程的管理和同步的問題。它可以開始翼悴,取消線程執(zhí)行缚够。他有兩個(gè)默認(rèn)的實(shí)現(xiàn)方法:NSInvocationOperation和NSBlockOperation。當(dāng)然我們也可以自定NSOperations鹦赎,只有實(shí)現(xiàn)里面的main方法即可

3? GCD:也是重點(diǎn)講的一個(gè)谍椅,它是ios4才開始使用的,當(dāng)然現(xiàn)在我們ios9都出來了古话,GCD的成熟度足可以讓我們放心的使用雏吭,它是基于C實(shí)現(xiàn)的,性能上要相對(duì)來說好一些陪踩,而且可以用最簡(jiǎn)單的代碼去實(shí)現(xiàn)復(fù)雜的線程問題杖们。

三) NSThread的基本使用方法

1.動(dòng)態(tài)初始化

NSThread threadOne = [[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];

//其中run是一個(gè)方法悉抵,我們通過方法來執(zhí)行多線程中得處理

[_threadOne setName:@"one"]; //給線程初始化一個(gè)別名

[_threadOne start];//開始執(zhí)行

2 靜態(tài)初始化

[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil]; //通過這一句代碼我們就可以創(chuàng)建出另一個(gè)線程出來并去執(zhí)行

3 創(chuàng)建隱式線程:

[self performSelectorInBackground:@selector(run) withObject:nil];

注:這是NSObject的一個(gè)方法,他可以讓一個(gè)耗時(shí)間的處理放入后臺(tái)去執(zhí)行摘完,但是在swift中拋棄了姥饰,原因是蘋果覺得這個(gè)方法是線程不安全的

4 獲取當(dāng)前的線程

NSThread *current = [NSThread currentThread];//返回的是目前的線程

5 返回主線程(刷新UI控件必須在主線程中執(zhí)行)

[self performSelectorOnMainThread:@selector(main:) withObject:nil waitUntilDone:YES];

6 等待(暫停)當(dāng)前的線程

[NSThread sleepForTimeInterval:3.0f] ;//3秒之后執(zhí)行

或者

NSDate *date = [NSDate dateWithTimeInterval:2 sinceDate:[NSDate date]];

[NSThread sleepUntilDate:date]; 等待date完成后再去執(zhí)行

注:前者是等待時(shí)間的完成孝治,后者是等待數(shù)據(jù)的完成

四)? NSOperation使用方法:

NSOperation 實(shí)例封裝了需要執(zhí)行的操作和執(zhí)行操作所需的數(shù)據(jù)列粪,并且能夠以并發(fā)或非并發(fā)的方式執(zhí)行這個(gè)操作。NSOperation在ios4后也基于GCD實(shí)現(xiàn)荆秦,但是相對(duì)于GCD來說可控性更強(qiáng)篱竭,并且可以加入操作依賴。NSOperation提供了ready cancelled executing finished這幾個(gè)狀態(tài)變化步绸,我們的開發(fā)也是必須處理自己關(guān)心的其中的狀態(tài)掺逼。這些狀態(tài)都是基于keypath的KVO通知決定,所以在你手動(dòng)改變自己關(guān)心的狀態(tài)時(shí)瓤介,請(qǐng)別忘了手動(dòng)發(fā)送通知吕喘。這里面每個(gè)屬性都是相互獨(dú)立的,同時(shí)只可能有一個(gè)狀態(tài)是YES刑桑。finished這個(gè)狀態(tài)在操作完成后請(qǐng)及時(shí)設(shè)置為YES氯质,因?yàn)镹SOperationQueue所管理的隊(duì)列中,只有isFinished為YES時(shí)才將其移除隊(duì)列祠斧,這點(diǎn)在內(nèi)存管理和避免死鎖很關(guān)鍵闻察。

1.NSInvocationOperation:

NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:nil];//紅色多線程中處理的方法

[op start]; //開始

[op cancel];//取消

2? NSBlockOperation

NSBlockOperation *block = [NSBlockOperation? ? blockOperationWithBlock:^{

NSLog(@"%@",[NSThread currentThread]); //處理線程的block方法

}];

3 NSOperationQueue

一個(gè)NSOperation對(duì)象可以通過調(diào)用start方法來執(zhí)行任務(wù),默認(rèn)是同步執(zhí)行的琢锋。也可以將NSOperation添加到一個(gè)NSOperationQueue(操作隊(duì)列)中去執(zhí)行辕漂,而且是異步執(zhí)行的。一旦NSoperation添加到NSoperationQueue中吴超,用戶就無權(quán)對(duì)NSoperation管理钉嘹,都有NSoperationQueue來執(zhí)行。

3.1 添加一個(gè)隊(duì)列

NSoperationQueue *myQueue = [[NSOperationQueue alloc]init];

NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:nil];

[myQueue addOperation:op];

3.2 主隊(duì)列(任何刷新UI的方法都必須在主隊(duì)列中執(zhí)行)

[[NSOperationQueue mainQueue]addOperationWithBlock:^{

//可以執(zhí)行刷新UI控件的方法

}];

3.3 隊(duì)列直接可以設(shè)置依賴鲸阻,比如隊(duì)列1需要隊(duì)列2執(zhí)行完畢后才能執(zhí)行(addDependency)

NSBlockOperation *block1 = [NSBlockOperation blockOperationWithBlock:^{

NSLog(@"%@",[NSThread currentThread]);

}];

NSBlockOperation *block2 = [NSBlockOperation blockOperationWithBlock:^{

NSLog(@"%@",[NSThread currentThread]);

}];

[block1 addDependency:block2];

[myQueue addOperation:block1];

[myQueue addOperation:block2];

3.4可以設(shè)置最大并發(fā)的操作數(shù)量

[myQueue setMaxConcurrentOperationCount:2];

3.5 一旦添加到隊(duì)列,隊(duì)列就擁有了這個(gè)Operation對(duì)象并且不能被? 刪除,唯一能做的事情是取消跋涣。

[myQueue cancelAllOperations];

3.6獲取NSOperation

myQueue.operations 這是一個(gè)數(shù)組,里面存放這添加進(jìn)入這個(gè)隊(duì)列的所有任務(wù)

3.7 如果你想臨時(shí)暫停Operations的執(zhí)行,可以使用queue的setSuspended:方法暫停queue鸟悴。

[myQueue setSuspended:YES];

四)GCD

1 GCD是Grand Central Dispatch的簡(jiǎn)稱陈辱,它是基于C語言的。如果使用GCD遣臼,完全由系統(tǒng)管理線程性置,我們不需要編寫線程代碼。只需定義想要執(zhí)行的任務(wù),然后添加到適當(dāng)?shù)恼{(diào)度隊(duì)列(dispatch queue)揍堰。GCD會(huì)負(fù)責(zé)創(chuàng)建線程和調(diào)度你的任務(wù)鹏浅,系統(tǒng)直接提供線程管理。

2 GCD的操作思想是講操作放在隊(duì)列中去執(zhí)行

1? 操作是用block來實(shí)現(xiàn)的

2 隊(duì)列是先進(jìn)先出的,它是負(fù)責(zé)調(diào)度任務(wù)執(zhí)行所在的線程

3 GCD分為串行和并行屏歹,有自定義隐砸,主隊(duì)列和全局隊(duì)列三種。一個(gè)同步函數(shù)只在完成了它預(yù)定的任務(wù)后才返回蝙眶。一個(gè)異步函數(shù)季希,剛好相反,會(huì)立即返回幽纷,預(yù)定的任務(wù)會(huì)完成但不會(huì)等它完成式塌。因此,一個(gè)異步函數(shù)不會(huì)阻塞當(dāng)前線程去執(zhí)行下一個(gè)函數(shù)友浸。如果在主隊(duì)列中執(zhí)行同步的話峰尝,會(huì)造成死鎖的發(fā)生

3 串行和并行

串行:一次只能執(zhí)行一個(gè)任務(wù), 當(dāng)前任務(wù)完成才開始出列并啟動(dòng)下一個(gè)任務(wù)

并行:則盡可能多地啟動(dòng)任務(wù)并發(fā)執(zhí)行

4GCD基本使用方法

1 自定義隊(duì)列

dispatch_queue_t q = dispatch_queue_create("gcdDemo1", DISPATCH_QUEUE_SERIAL); DISPATCH_QUEUE_SERIAL:串行,可以傳入nil 默認(rèn)是串行收恢,"gcdDemo1”是這個(gè)線程的別名武学,可以傳nil

dispatch_queue_t q = dispatch_queue_create("gcdDemo2", DISPATCH_QUEUE_CONCURRENT);? DISPATCH_QUEUE_CONCURRENT:并行

dispatch_async(q, ^{? ? 注:異步執(zhí)行,可以開辟多個(gè)線程去執(zhí)行伦意,無需等待

NSLog(@"%@",[NSThread currentThread]);

});

dispatch_sync(q, ^{? 注:同步執(zhí)行火窒,只開辟一個(gè)線程,需要等待上一個(gè)任務(wù)的完成才能執(zhí)行

NSLog(@"%@",[NSThread currentThread]);

});

2 全局隊(duì)列

dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

DISPATCH_QUEUE_PRIORITY_DEFAULT:默認(rèn)的驮肉,全局隊(duì)列是有優(yōu)先級(jí)的

DISPATCH_QUEUE_PRIORITY_HIGH? ? ? 最高(優(yōu)先執(zhí)行)

DISPATCH_QUEUE_PRIORITY_DEFAULT? ? 默認(rèn)

DISPATCH_QUEUE_PRIORITY_LOW? ? ? ? 最低

DISPATCH_QUEUE_PRIORITY_BACKGROUND 后臺(tái)

3 主隊(duì)列

dispatch_queue_t q = dispatch_get_main_queue();

每一個(gè)應(yīng)用程序都有一個(gè)主線程? 在ios中所有的ui刷新都再主線程中執(zhí)行熏矿!這是因?yàn)樘O果為了提高性能,大部分庫都是線程不安全的离钝,如果在子線程刷新控件會(huì)造成一些問題票编,所有所有的UI控件的刷新都由主線程上刷新

4 延遲執(zhí)行

dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull * NSEC_PER_SEC);

dispatch_after(time, dispatch_get_main_queue(), ^{

NSLog(@"我是3秒才執(zhí)行的!");

});

5 dispatchGroup組隊(duì)列

dispatchGroup作用:當(dāng) dispatch_group_async函數(shù)將多個(gè)任務(wù)關(guān)聯(lián)到一個(gè)Dispatch Group和相應(yīng)的queue中,group會(huì)并發(fā)地同時(shí)執(zhí)行這些任務(wù)奈辰。而且Dispatch Group可以用來阻塞一個(gè)線程, 直到group關(guān)聯(lián)的所有的任務(wù)完成執(zhí)行栏妖。有時(shí)候你必須等待任務(wù)完成的結(jié)果,然后才能繼續(xù)后面的處理。

dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group, q, ^{

NSLog(@"1 == %@",[NSThread currentThread]);

});

dispatch_group_async(group, q, ^{

NSLog(@"2 == %@",[NSThread currentThread]);

});

dispatch_group_async(group, q, ^{

NSLog(@"3 == %@",[NSThread currentThread]);

});

dispatch_group_notify(group, dispatch_get_main_queue(), ^{//不管前面的線程誰先執(zhí)行奖恰,最后都會(huì)執(zhí)行notify方法吊趾。

NSLog(@"4 == %@",[NSThread currentThread]);

});

6 dispathc_apply

dispathc_apply是dispatch_sync 和dispatch_group的關(guān)聯(lián)API.它以指定的次數(shù)將指定的Block加入到指定的隊(duì)列中。并等待隊(duì)列中操作全部完成.

dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_apply(10, globalQueue, ^(size_t index) {

NSLog(@"%zu",index);

dispatch_source_merge_data(socurce, 1);

});

7 dispatch_source_t 信號(hào)源

dispatch source是一個(gè)監(jiān)視某些類型事件的對(duì)象瑟啃。當(dāng)這些事件發(fā)生時(shí)论泛,它自動(dòng)將一個(gè)block放入一個(gè)dispatch queue的執(zhí)行例程中。書中定義蛹屿。我的理解就是多線程中得KVO屁奏,它檢測(cè)用戶事件,它是由dispatch_source_merge_data函數(shù)來向自己發(fā)送信號(hào)错负,然后通過dispatch_source_set_event_handler這個(gè)函數(shù)去執(zhí)行坟瓢。

這是我寫了一個(gè)進(jìn)度條的例子

執(zhí)行部分:? __weak __typeof(self)weakSelf = self;

dispatch_source_t? socurce = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_main_queue());

dispatch_source_set_event_handler(socurce, ^{

[weakSelf.progressIndicator setProgress:dispatch_source_get_data(socurce)? animated:YES];

});

dispatch_resume(socurce);

監(jiān)聽部分:? ? dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_apply(10, globalQueue, ^(size_t index) {

NSLog(@"%zu",index);

dispatch_source_merge_data(socurce, 1);

});

/*

dispatch_source_create(dispatch_source_type_t type,

uintptr_t handle,

unsigned long mask,

dispatch_queue_t queue);

第1個(gè)參數(shù):要監(jiān)聽的事件類型

第2個(gè)參數(shù):可以理解為句柄勇边、索引或id,假如要監(jiān)聽進(jìn)程折联,需要傳入進(jìn)程的ID

第3個(gè)參數(shù):根據(jù)參數(shù)2粒褒,可以理解為描述,提供更詳細(xì)的描述诚镰,讓它知道具體要監(jiān)聽什么

第4個(gè)參數(shù):當(dāng)事件發(fā)生時(shí)奕坟,將block添加至哪個(gè)隊(duì)列來執(zhí)行

**/

8 dispatch_semaphore信號(hào)量

當(dāng)我們?cè)谔幚硪幌盗芯€程的時(shí)候,當(dāng)數(shù)量達(dá)到一定量清笨,在以前我們可能會(huì)選擇使用NSOperationQueue來處理并發(fā)控制月杉,在GCD中我們需要通過dispatch_semaphore來控制它的并發(fā)數(shù)量。

dispatch_group_t group = dispatch_group_create();

dispatch_semaphore_t semaphore = dispatch_semaphore_create(5);

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

for (int i = 0; i < 10; i++)

{

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);//如果技術(shù)器的數(shù)值大于等于1的時(shí)候進(jìn)行-1操作

dispatch_group_async(group, queue, ^{

NSLog(@"----%d",i);

sleep(2);

dispatch_semaphore_signal(semaphore);//計(jì)數(shù)器+1

});

}

簡(jiǎn)單的介紹一下這一段代碼抠艾,創(chuàng)建了一個(gè)初使值為5的semaphore苛萎,每一次for循環(huán)都會(huì)創(chuàng)建一個(gè)新的線程,線程結(jié)束的時(shí)候會(huì)發(fā)送一個(gè)信號(hào)跌帐,線程創(chuàng)建之前會(huì)信號(hào)等待首懈,所以當(dāng)同時(shí)創(chuàng)建了5個(gè)線程之后,for循環(huán)就會(huì)阻塞谨敛,等待有線程結(jié)束之后會(huì)增加一個(gè)信號(hào)才繼續(xù)執(zhí)行究履,如此就形成了對(duì)并發(fā)的控制,如上就是一個(gè)并發(fā)數(shù)為5的一個(gè)線程隊(duì)列脸狸。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末最仑,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子炊甲,更是在濱河造成了極大的恐慌泥彤,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卿啡,死亡現(xiàn)場(chǎng)離奇詭異吟吝,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)颈娜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門剑逃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人官辽,你說我怎么就攤上這事蛹磺。” “怎么了同仆?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵萤捆,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng)俗或,這世上最難降的妖魔是什么市怎? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮蕴侣,結(jié)果婚禮上焰轻,老公的妹妹穿的比我還像新娘臭觉。我一直安慰自己昆雀,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布蝠筑。 她就那樣靜靜地躺著狞膘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪什乙。 梳的紋絲不亂的頭發(fā)上挽封,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音臣镣,去河邊找鬼辅愿。 笑死,一個(gè)胖子當(dāng)著我的面吹牛忆某,可吹牛的內(nèi)容都是我干的点待。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼弃舒,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼癞埠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起聋呢,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤苗踪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后削锰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體通铲,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年器贩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了颅夺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡磨澡,死狀恐怖碗啄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情稳摄,我是刑警寧澤稚字,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響胆描,放射性物質(zhì)發(fā)生泄漏瘫想。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一昌讲、第九天 我趴在偏房一處隱蔽的房頂上張望国夜。 院中可真熱鬧,春花似錦短绸、人聲如沸车吹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窄驹。三九已至,卻和暖如春证逻,著一層夾襖步出監(jiān)牢的瞬間乐埠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國打工囚企, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留丈咐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓龙宏,卻偏偏與公主長(zhǎng)得像棵逊,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子烦衣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

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

  • 一歹河、前言 上一篇文章iOS多線程淺匯-原理篇中整理了一些有關(guān)多線程的基本概念。本篇博文介紹的是iOS中常用的幾個(gè)多...
    nuclear閱讀 2,047評(píng)論 6 18
  • NSThread 第一種:通過NSThread的對(duì)象方法 NSThread *thread = [[NSThrea...
    攻城獅GG閱讀 795評(píng)論 0 3
  • 最近大家都在學(xué)習(xí)跟項(xiàng)目有關(guān)的知識(shí)花吟,有跟項(xiàng)目源碼學(xué)習(xí)有關(guān)的學(xué)習(xí)卡秸歧,也有跟項(xiàng)目有關(guān)的技術(shù)學(xué)習(xí)卡,比如:Jenkins,...
    Yvette14閱讀 577評(píng)論 3 1
  • Kiki_Shmoo閱讀 156評(píng)論 0 3
  • 不知怎么衅澈,這學(xué)期就是對(duì)很多事情都不感興趣键菱,對(duì)籃球不感興趣,對(duì)學(xué)習(xí)也沒興趣今布,對(duì)什么事都覺得沒有意思经备。 狀態(tài)有些不...
    叁TROIS閱讀 193評(píng)論 0 1