日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

25个增强iOS应用程序性能的提示和技巧 — 中级篇

發(fā)布時(shí)間:2023/11/27 生活经验 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 25个增强iOS应用程序性能的提示和技巧 — 中级篇 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文由破船譯自:raywenderlich
轉(zhuǎn)載請(qǐng)注明出處:BeyondVincent的博客
_____________

在開發(fā)iOS應(yīng)用程序時(shí)。讓程序具有良好的性能是非常關(guān)鍵的。這也是用戶所期望的。假設(shè)你的程序執(zhí)行遲鈍或緩慢,會(huì)招致用戶的差評(píng)。

然而由于iOS設(shè)備的局限性,有時(shí)候要想獲得良好的性能。是非常困難的。在開發(fā)過程中,有很多事項(xiàng)須要記住。而且關(guān)于性能影響非常easy就忘記。

這就是為什么我要寫這篇文章。本文收集了25個(gè)關(guān)于能夠提升程序性能的提示和技巧。

文件夾

我把性能優(yōu)化技巧分為3個(gè)不同的等級(jí):0基礎(chǔ)、中級(jí)和高級(jí)

中級(jí)

在性能優(yōu)化時(shí),當(dāng)你碰到一些復(fù)雜的問題。應(yīng)該注意和使用例如以下技巧:

  1. 重用和延遲載入View
  2. 緩存、緩存、緩存
  3. 考慮繪制
  4. 處理內(nèi)存警告
  5. 重用花銷非常大的對(duì)象
  6. 使用Sprite Sheets
  7. 避免又一次處理數(shù)據(jù)
  8. 選擇正確的數(shù)據(jù)格式
  9. 設(shè)置適當(dāng)?shù)谋尘皥D片
  10. 降低Web內(nèi)容的影響
  11. 設(shè)置陰影路徑
  12. 優(yōu)化TableView
  13. 選擇正確的數(shù)據(jù)存儲(chǔ)方式

?

中級(jí)性能提升

如今。在進(jìn)行代碼優(yōu)化時(shí),你已經(jīng)能夠完畢一些0基礎(chǔ)性能優(yōu)化了。

可是以下還有另外一些優(yōu)化方案,盡管可能不太明顯(取決于程序的架構(gòu)和相關(guān)代碼),可是,假設(shè)能夠正確的利用好這些方案,那么它們對(duì)性能的優(yōu)化將非常明顯!


9) 重用和延遲載入View

程序界面中包括很多其它的view。意味著界面在顯示的時(shí)候。須要進(jìn)行很多其它的繪制任務(wù)。也就意味著須要消耗很多其它的CPU和內(nèi)存資源。

特別是在一個(gè)UIScrollView里面加入了很多view。

這樣的情況的管理技巧能夠參考UITableView和UICollectionView的行為:不要一次性創(chuàng)建全部的subview。而是在須要的時(shí)候在創(chuàng)建view。而且當(dāng)view使用完畢時(shí)候?qū)⑺鼈兗尤氲街赜藐?duì)列中。

這樣就能夠僅在UIScrollView滾動(dòng)的時(shí)候才配置view,以此能夠避免分配創(chuàng)建view的帶來的成本——這可能是非常耗資源的。

如今有這樣的一個(gè)問題:在程序中須要顯示的view在什么時(shí)機(jī)創(chuàng)建(比方說,當(dāng)用戶點(diǎn)擊某個(gè)button,須要顯示某個(gè)view)。這里有兩種可選方法:

  1. 在屏幕第一次載入以及隱藏的時(shí)候,創(chuàng)建view;然后在須要的時(shí)候。再把view顯示出來。
  2. 直到須要顯示view的時(shí)候,才創(chuàng)建并顯示view。

每種方法都有各自的長處和確定。

使用第一種方法,須要消耗很多其它的內(nèi)容,由于創(chuàng)建出來的view一直占領(lǐng)著內(nèi)存。直到view被release掉。只是,使用這樣的方法。當(dāng)用戶點(diǎn)擊button時(shí),程序會(huì)非常快的顯示出view,由于僅僅須要改動(dòng)一下view的可見性就可以。

而使用另外一種方法則產(chǎn)生相反的效果;當(dāng)須要的時(shí)候猜創(chuàng)建view,這會(huì)消耗更少的內(nèi)存。只是。當(dāng)用戶點(diǎn)擊button的時(shí)候,不會(huì)馬上顯示出view。


10) 緩存、緩存、緩存

在開發(fā)程序時(shí),一個(gè)重要的規(guī)則就是“緩存重要的內(nèi)容”——這些內(nèi)容一般不會(huì)改變,而且訪問的頻率比較高。

能夠緩存寫什么內(nèi)容呢?比方遠(yuǎn)程server的響應(yīng)內(nèi)容,圖片,甚至是計(jì)算結(jié)果,比方UITableView的行高。

NSURLConnection依據(jù)HTTP頭的處理過程,已經(jīng)把一些資源緩存到磁盤和內(nèi)存中了。你甚至能夠手動(dòng)創(chuàng)建一個(gè)NSURLRequest 。讓其僅僅載入緩存的值。

以下的代碼片段一般用在為圖片創(chuàng)建一個(gè)NSURLRequest:

+ (NSMutableURLRequest *)imageRequestWithURL:(NSURL *)url {NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];request.cachePolicy = NSURLRequestReturnCacheDataElseLoad; // this will make sure the request always returns the cached imagerequest.HTTPShouldHandleCookies = NO;request.HTTPShouldUsePipelining = YES;[request addValue:@"image/*" forHTTPHeaderField:@"Accept"];return request;
}

注意:你能夠使用NSURLConnection抓取一個(gè)URL請(qǐng)求,可是相同能夠使用AFNetworking來抓取。這樣的方法不用改動(dòng)全部網(wǎng)絡(luò)相關(guān)的代碼——這是一個(gè)技巧!

:]

假設(shè)你要直到很多其它關(guān)于HTTP 緩存, NSURLCache, NSURLConnection 以及相關(guān)的內(nèi)容, 那么看一下NSHipster中的the NSURLCache entry

假設(shè)你須要緩存的內(nèi)容沒涉及到HTTP請(qǐng)求。那么使用NSCache。

NSCache的外觀和行為與NSDictionary相似, 可是,當(dāng)系統(tǒng)須要回收內(nèi)存時(shí),NSCache會(huì)自己主動(dòng)的里面存儲(chǔ)的內(nèi)容。Mattt Thompson 在NSHipster上寫了一篇關(guān)于NSCache非常不錯(cuò)的文章

假設(shè)還想知道關(guān)于HTTP緩存很多其它的內(nèi)容,那么建議閱讀一下Google的這篇文章:best-practices document on HTTP caching


  • 11) 考慮繪制*

考慮繪制

?

在iOS中制作美麗的button有多種方法。

能夠使用全尺寸圖片。可縮放圖片。或者使用CALayer, CoreGraphics, 甚至是OpenGL來手動(dòng)測(cè)量和繪制button。

當(dāng)然,這些方法的復(fù)雜程度也不同,而且性能也有所差別。這里有一篇相關(guān)文章值得閱讀一下:關(guān)于iOS中圖形的性能

當(dāng)中Andy Matuschak(以前是蘋果的UIKit小組的組員)對(duì)這篇文章的評(píng)論中,對(duì)于不同的方法及其性能權(quán)衡有非常好的一個(gè)見解。

簡單來說,使用預(yù)渲染圖片技術(shù)是最快的,由于iOS中不用等到在屏幕上顯示的時(shí)候才創(chuàng)建圖形和對(duì)形狀進(jìn)行繪制(圖片已經(jīng)創(chuàng)建好了!)。

這樣帶來的問題是須要把全部的圖片都放到程序bundle中。從而添加了程序的大小。因此使用可伸縮圖片在這里將排上用場(chǎng)了:能夠移除“浪費(fèi)”空間的圖片——iOS能夠反復(fù)利用。而且針對(duì)不同的元素(比如button)不須要?jiǎng)?chuàng)建不同的圖片。

只是,使用圖片的話會(huì)失去代碼對(duì)圖片的控制能力,進(jìn)而針對(duì)不同的程序。就須要反復(fù)的生成每個(gè)須要的圖片。并反復(fù)的放到每個(gè)程序中。這個(gè)處理過程通常會(huì)比較慢。另外一點(diǎn)就是假設(shè)你須要一個(gè)動(dòng)畫,或者很多圖片都要進(jìn)行輕微的調(diào)整(比方多個(gè)顏色的覆蓋)。那么須要在程序中加入很多圖片,進(jìn)而添加了程序bundle的大小。

總的來說,你須要考慮一下什么才是最重要的:繪制性能還是程序大小。一般來說都重要,所以在同一個(gè)project中,應(yīng)該兩種都應(yīng)考慮。


12) 處理內(nèi)存警告

當(dāng)系統(tǒng)內(nèi)存偏低時(shí),iOS會(huì)通知全部在執(zhí)行的程序。蘋果的官方文檔中介紹了怎樣處理低內(nèi)存警告:

If your app receives this warning, it must free up as much memory as possible. The best way to do this is to remove strong references to caches, image objects, and other data objects that can be recreated later.

假設(shè)程序收到了低內(nèi)存警告,在程序中必須盡量釋放內(nèi)存。

最佳方法就是移除強(qiáng)引用的涉及到的緩存,圖片對(duì)象,以及其它能夠在之后使用時(shí)還能夠又一次創(chuàng)建的數(shù)據(jù)對(duì)象。

UIKit中提供了例如以下幾種方法來接收低內(nèi)存(low-memory)警告:

  • 實(shí)現(xiàn)app delegate中的applicationDidReceiveMemoryWarning: 方法。
  • 在UIViewController子類中重寫(Override)didReceiveMemoryWarning方法。

  • 在通知中心里面注冊(cè)UIApplicationDidReceiveMemoryWarningNotificatio通知。

在收到以上隨意的警告時(shí),須要馬上釋放不論什么不須要的內(nèi)存。

比如,UIViewController的默認(rèn)情況是清除掉當(dāng)前不可見的view;在UIViewController的子類中,能夠清除一些額外的數(shù)據(jù)。程序中不沒有顯示在當(dāng)前屏幕中的圖片也能夠release掉。

當(dāng)收到低內(nèi)存警告時(shí)。盡量釋放內(nèi)存是非常重要的。否則,執(zhí)行中的程序有可能會(huì)被系統(tǒng)殺掉。

只是,在清除內(nèi)存時(shí)要注意一下:確保被清除的對(duì)象之后還能夠被創(chuàng)建出來。另外,在開發(fā)程序的時(shí)候。請(qǐng)使用iOS模擬器中的模擬內(nèi)存警告功能對(duì)程序進(jìn)行測(cè)試!


13) 重用花銷非常大的對(duì)象

有些對(duì)象的初始化非常慢——比方NSDateFormatter和NSCalendar。只是有時(shí)候能夠避免使用這些對(duì)象,比如在解析JSON/XML中的日期時(shí)。

當(dāng)使用這些對(duì)象時(shí)。為了避免性能上的瓶頸,能夠嘗試盡量重用這些對(duì)象——在類中加入一個(gè)屬性或者創(chuàng)建一個(gè)靜態(tài)變量。

注意。假設(shè)使用靜態(tài)變量的話,對(duì)象會(huì)在程序執(zhí)行的時(shí)候一直存在,就像單例一樣。

以下的代碼演示創(chuàng)建一個(gè)延遲載入的日期格式屬性。第一次調(diào)用屬性的時(shí)候。會(huì)創(chuàng)建一個(gè)新的日期格式。

之后再調(diào)用的話。會(huì)返回已經(jīng)創(chuàng)建好的實(shí)例對(duì)象:

// in your .h or inside a class extension
@property (nonatomic, strong) NSDateFormatter *formatter;// inside the implementation (.m)
// When you need, just use self.formatter
- (NSDateFormatter *)formatter {if (! _formatter) {_formatter = [[NSDateFormatter alloc] init];_formatter.dateFormat = @"EEE MMM dd HH:mm:ss Z yyyy"; // twitter date format}return _formatter;
}

另外,還須要記住的是在設(shè)置NSDateFormatter的日期格式時(shí)。相同跟創(chuàng)建新的一個(gè)NSDateFormatter實(shí)例對(duì)象時(shí)一樣慢!

因此。在程序中假設(shè)須要頻繁的處理日期格式。那么對(duì)NSDateFormatter進(jìn)行重用是非常好的。


  • 14) 使用Sprite Sheets*

使用sprite sheets

你是一個(gè)游戲開發(fā)人員嗎?是的話那么sprite sheets是最佳選擇之中的一個(gè)。

使用Sprite sheets跟經(jīng)常使用的繪制方法比起來。繪制更快,而且消耗更少的內(nèi)存。

以下是兩個(gè)非常不錯(cuò)的sprite sheets教程:

  1. 怎樣在Cocos2D中使用動(dòng)畫和Sprite Sheets
  2. 怎樣在Cocos2D中使用紋理包(Texture Packer)和像素格式來創(chuàng)建并優(yōu)化Sprite Sheets

第二個(gè)教程詳細(xì)的介紹了像素格式——在游戲中能夠衡量性能的影響。

假設(shè)你還不熟悉sprite sheets。那么能夠看看這里的介紹:SpriteSheets – 視頻, Part 1and?Part 2.?這兩個(gè)視頻的作者是Andreas L?w, 他是紋理包(Texture Packer)的創(chuàng)建者, 紋理包是創(chuàng)建sprite sheets的重要工具。

除了使用sprite sheets外,這里還介紹了一些用于游戲開發(fā)中的技巧,比如。假設(shè)你有非常多sprite(比方射擊類游戲中),那么能夠重用sprite,而不用每次都創(chuàng)建sprite。


15) 避免又一次處理數(shù)據(jù)

很多程序都須要從遠(yuǎn)程server中獲取數(shù)據(jù),以滿足程序的需求。這些數(shù)據(jù)通常是JSON或XML格式。在請(qǐng)求和接收數(shù)據(jù)時(shí),使用相同的數(shù)據(jù)結(jié)構(gòu)非常重要。

為什么呢?在內(nèi)存中把數(shù)據(jù)轉(zhuǎn)換為適合程序的數(shù)據(jù)格式是須要付出額外代價(jià)的。

比如。假設(shè)你須要在table view中顯示一些數(shù)據(jù)。那么請(qǐng)求和接收的數(shù)據(jù)格式最好是數(shù)組格式的。這樣能夠避免一些中間操作——將數(shù)據(jù)轉(zhuǎn)換為適合程序使用的數(shù)據(jù)結(jié)構(gòu)。

相似的,假設(shè)程序是依據(jù)鍵來訪問詳細(xì)的值,那么最好請(qǐng)求和接收一個(gè)鍵/值對(duì)字典。

在第一時(shí)間獲得的數(shù)據(jù)就是所須要格式的,能夠避免將數(shù)據(jù)轉(zhuǎn)換為適合程序的數(shù)據(jù)格式帶來的額外代價(jià)。


  • 16) 選擇正確的數(shù)據(jù)格式*

選擇正確的數(shù)據(jù)格式

?

將數(shù)據(jù)從程序傳到網(wǎng)絡(luò)server中有多種方法,當(dāng)中使用的數(shù)據(jù)格式基本都是JSON和XML。

你須要做的就是在程序中選擇正確的數(shù)據(jù)格式。

JSON的解析速度非常快。而且要比XML小得多。也就意味著僅僅須要傳輸更少數(shù)據(jù)。

而且在iOS5之后,已經(jīng)有內(nèi)置的JSON反序列化API了。所以使用JSON是非常easy的。

只是XML也有它自己的優(yōu)勢(shì):假設(shè)使用SAX方法來解析XML。那么能夠邊讀XML邊解析。并不用等到全部的XML獲取到了才開始解析。這與JSON是不同的。當(dāng)處理大量數(shù)據(jù)時(shí),這樣的方法能夠提升性能并降低內(nèi)存的消耗。


17) 設(shè)置適當(dāng)?shù)谋尘皥D片

在iOS編碼中,跟別的很多東西相似。這里也有兩種方法來給view設(shè)置一個(gè)背景圖片:

  1. 能夠使用UIColor的colorWithPatternImge方法來創(chuàng)建一個(gè)顏色,并將這個(gè)顏色設(shè)置為view的背景顏色。
  2. 能夠給view加入一個(gè)UIImageView子視圖。

假設(shè)你有一個(gè)全尺寸的背景圖片,那么應(yīng)該使用UIImageView。由于UIColor的colorWithPatternImge方法是用來創(chuàng)建小圖片的——該圖片會(huì)被反復(fù)使用。

此時(shí)使用UIImageView會(huì)節(jié)省非常多內(nèi)存。

// You could also achieve the same result in Interface Builder
UIImageView *backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background"]];
[self.view addSubview:backgroundView];

只是,假設(shè)你計(jì)劃用小圖片當(dāng)做背景。那么應(yīng)該使用UIColor的colorWithPatternImge方法。

這樣的情況下繪制速度會(huì)非常快,而且不會(huì)消耗大量的內(nèi)存。

self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"background"]];


18) 降低Web內(nèi)容的影響

UIWebView非常實(shí)用。用它能夠非常easy的顯示web內(nèi)容,甚至能夠構(gòu)建UIKit空間難以顯示的內(nèi)容。

只是,你能夠能已經(jīng)注意到程序中使用的UIWebView組建沒有蘋果的Safari程序快。這是由于JIT編譯限制了WebKit的Nitro引擎的使用。

因此為了獲得更加的性能,須要調(diào)整一下HTML的大小。首先就是盡量的擺脫JavaScript,并避免使用大的礦建,比如jQuery。有時(shí)候使用原始的JavaScript要比別的框架快。

另外,盡量的異步載入JavaScript文件——特別是不直接影響到頁面行為時(shí),比如分析腳本。

最后——讓使用到的圖片,跟實(shí)際須要的一樣大小。如之前提到的,盡量使用sprite sheets,以此節(jié)省內(nèi)存和提升速度。

很多其它相關(guān)信息,能夠看一下:?WWDC 2012 session #601 – 在iOS中優(yōu)化UIWebView和站點(diǎn)中的Web內(nèi)容。


19) 設(shè)置陰影路徑

假設(shè)須要在view活layer中加入一個(gè)陰影。該怎樣處理呢?

大多數(shù)開發(fā)人員首先將QuartzCore框架加入到project中,然后加入例如以下代碼:

#import <QuartzCore/QuartzCore.h>// Somewhere later ...
UIView *view = [[UIView alloc] init];// Setup the shadow ...
view.layer.shadowOffset = CGSizeMake(-1.0f, 1.0f);
view.layer.shadowRadius = 5.0f;
view.layer.shadowOpacity = 0.6;

看起來非常easy。不是嗎?

然而不幸的是上面這樣的方法有一個(gè)問題。

Core Animation在渲染陰影效果之前,必須通過做一個(gè)離屏(offscreen)才干確定view的形狀。而這個(gè)離屏操作非常耗費(fèi)資源。

以下有一種方法能夠更easy的讓系統(tǒng)進(jìn)行陰影渲染:設(shè)置陰影路徑!

view.layer.shadowPath = [[UIBezierPath bezierPathWithRect:view.bounds] CGPath];

通過設(shè)置陰影路徑,iOS就不用總是再計(jì)算該怎樣繪制陰影了。僅僅須要使用你預(yù)先計(jì)算好的路徑就可以。

有一點(diǎn)不好的是,依據(jù)view的格式,自己可能非常難計(jì)算出路徑。另外一個(gè)問題就是當(dāng)view的frame改變時(shí),必須每次都更新一下陰影路徑。

假設(shè)你想了解很多其它相關(guān)信息,Mark Pospesel寫了一篇非常棒的文章:shadowPath


20) 優(yōu)化TableView

Table views須要高速的滾動(dòng)——假設(shè)不能的話。用戶會(huì)感覺到停頓。

為了讓table view平滑的滾動(dòng)。確保遵循了例如以下建議:

  • 設(shè)置正確的reuseIdentifer以重用cell。
  • 盡量將view設(shè)置為不透明。包括cell本身。
  • 避免漸變,圖像縮放以及離屏繪制。
  • 假設(shè)row的高度不相同,那么將其緩存下來。
  • 假設(shè)cell顯示的內(nèi)容來此網(wǎng)絡(luò)。那么確保這些內(nèi)容是通過異步來獲取的。
  • 使用shadowPath來設(shè)置陰影。

  • 降低subview的數(shù)量。
  • 在cellForRowAtIndexPath:中盡量做更少的操作。

    假設(shè)須要做一些處理,那么最好做過一次之后,就將結(jié)果緩存起來。

  • 使用適當(dāng)?shù)臄?shù)據(jù)結(jié)構(gòu)來保存須要的信息。不同的結(jié)構(gòu)會(huì)帶來不同的操作代價(jià)。
  • 使用rowHeight, sectionFooterHeight 和 sectionHeaderHeight 來設(shè)置一個(gè)恒定 高度。而不要從delegate中獲取。


  • 21) 選擇正確的數(shù)據(jù)存儲(chǔ)方式*

選擇正確的數(shù)據(jù)存儲(chǔ)方式


當(dāng)須要存儲(chǔ)和讀取大量的數(shù)據(jù)時(shí),該怎樣選擇存儲(chǔ)方式呢?

有例如以下選擇:

  • 使用NSUserDefaults進(jìn)行存儲(chǔ)
  • 保存為XML。JSON或Plist格式的文件
  • 利用NSCoding進(jìn)行歸檔
  • 存儲(chǔ)到一個(gè)本地?cái)?shù)據(jù)庫,比如SQLite。

  • 使用Core Data.

使用NSUserDefaults有什么問題呢? 盡管NSUserDefaults非常好而且easy。只是僅僅僅僅針對(duì)于存儲(chǔ)小量數(shù)據(jù)(比方你的級(jí)別,或者聲音是開或關(guān))。假設(shè)要存儲(chǔ)大量的數(shù)據(jù)。最好選擇別的存儲(chǔ)方式。

大量數(shù)據(jù)保存為結(jié)構(gòu)化的文件也可能會(huì)帶來問題。一般,在解析這些結(jié)構(gòu)數(shù)據(jù)之前,須要將內(nèi)容全部載入到內(nèi)存中。這是非常消耗資源的。盡管能夠使用SAX來處理XML文件,可是這有點(diǎn)復(fù)雜。

另外,載入到內(nèi)存中的全部對(duì)象,不一定全部都須要用到。

那么使用NSCoding來保存大量數(shù)據(jù)怎么樣呢?由于它相同是對(duì)文件進(jìn)行讀寫,因此依舊存在上面說的問題。

要保存大量的數(shù)據(jù),最好使用SQLite或Core Data。通過SQLite或Core Data能夠進(jìn)行詳細(xì)的查詢——僅僅須要獲取并載入須要的數(shù)據(jù)對(duì)象——避免對(duì)數(shù)據(jù)進(jìn)行不合理的搜索。在性能方面。SQLite和Core Data差不大。

SQLite和Core Data最大的差別實(shí)際上就是使用方法上。Core Data代表一個(gè)對(duì)象模型,而SQLite僅僅是一個(gè)DBMS。一般,蘋果建議使用Core Data,只是假設(shè)你有特殊的原因不能使用Core Data的話,能夠使用低級(jí)別的SQLite。

在程序中,假設(shè)選擇使用SQLite。這里有個(gè)方便的庫FMDB?:能夠利用該庫操作SQLite數(shù)據(jù)庫,而不用深入使用SQLite C API。

25個(gè)增強(qiáng)iOS應(yīng)用程序性能的提示和技巧 — 0基礎(chǔ)篇
25個(gè)增強(qiáng)iOS應(yīng)用程序性能的提示和技巧 — 高級(jí)篇

轉(zhuǎn)載于:https://www.cnblogs.com/mqxnongmin/p/10705851.html

總結(jié)

以上是生活随笔為你收集整理的25个增强iOS应用程序性能的提示和技巧 — 中级篇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。