王zi如測(cè)評(píng) 之 圓角對(duì)iPhone手機(jī)FPS的影響

首先標(biāo)題是隨性創(chuàng)造,如有雷同純屬巧合罩驻!為什么要寫這篇文章?最近在搞xamarin開發(fā),做個(gè)控件圓角難做得蛋疼表窘。很是懷念OC的實(shí)現(xiàn)。然后一個(gè)興起做了這個(gè)評(píng)測(cè)纱耻。
本評(píng)測(cè)主要是探討在多種方式下實(shí)現(xiàn)iOS圓角的實(shí)現(xiàn)领突,對(duì)FPS(frames per second ==幀每秒)的影響。

先來來個(gè)對(duì)比:請(qǐng)問案例一卡頓還是案例二卡頓?

案例一
案例二

答案就是:答案自找

ok琳袄,先來說說畫圓角的方式:

1. 使用layer江场,這應(yīng)該是我們最常用的方法了,兩代碼解決戰(zhàn)斗窖逗。

view.layer.masksToBounds = YES; ```
上圖:
![layer方式畫圓](http://upload-images.jianshu.io/upload_images/271180-fa5d7313ed0bbebb.gif?imageMogr2/auto-orient/strip)

![FPS](http://upload-images.jianshu.io/upload_images/271180-fe0fddf5da896c9a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

可以從圖中知道址否,在滑動(dòng)tableview時(shí),fps只有18碎紊、19(正常60)佑附。這種狀態(tài)有個(gè)俗語:“卡出翔”。
簡(jiǎn)略代碼:

UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"threeCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"threeCell"];
...
...
UIImageView * view = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"hehe"]];
view.frame = CGRectMake(0, 0, 44, 44);
view.layer.cornerRadius = 22;
view.layer.masksToBounds = YES;
// view.layer.shouldRasterize = YES;
// view.layer.rasterizationScale = [UIScreen mainScreen].scale;
[cell addSubview:view];
...

我們得想辦法優(yōu)化ho矮慕,然后Google了下就有了上面注釋的兩行代碼帮匾。
想必大家也留意到這兩行代碼

// view.layer.shouldRasterize = YES;
// view.layer.rasterizationScale = [UIScreen mainScreen].scale;

加上以后,大家可以看看效果痴鳄。
![11-12的fps](http://upload-images.jianshu.io/upload_images/271180-66cb1e414b7bcb88.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
更加卡了瘟斜,怎么辦呢?為啥呢痪寻?

其實(shí)這兩句話不應(yīng)該放在這個(gè)地方螺句,應(yīng)該在cell.layer上面添加。

cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;

修改了地方以后橡类,我們?cè)倏纯葱Ч?![cell.layer.shouldRasterize](http://upload-images.jianshu.io/upload_images/271180-fb70a1d1fd8bd877.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

添加這兩句代碼后蛇尚,能將你的幀數(shù)提高到50以上,```shouldRasterize = YES```會(huì)使視圖渲染內(nèi)容被緩存起來顾画,下次繪制的時(shí)候可以直接顯示緩存取劫。但這的前提是得保證內(nèi)容不變的情況下。如果你的圖片是變化的研侣,這可能也會(huì)對(duì)性能造成影響谱邪。

##2.drawrect

UIImage * myImage = [UIImage imageNamed:@"hehe"];
CGContextRef ctx = UIGraphicsGetCurrentContext();

CGContextSaveGState(ctx);//保存上下文
CGContextAddEllipseInRect(ctx,CGRectMake(105, 5, 40, 40));//因?yàn)橹灰_定了矩形框,圓或者是橢圓就確定了庶诡。
CGContextClip(ctx);

CGContextTranslateCTM(ctx, 0, 50);
CGContextScaleCTM(ctx, 1, -1);
CGContextDrawImage(ctx, CGRectMake(100, 0, 50, 50), [myImage CGImage]);
CGContextRestoreGState(ctx);//恢復(fù)狀態(tài)后惦银,就不會(huì)受裁剪的影響,不然只能在剪裁

![drawrect.gif](http://upload-images.jianshu.io/upload_images/271180-5b3ab5f2a80b168b.gif?imageMogr2/auto-orient/strip)


![drawrect.png](http://upload-images.jianshu.io/upload_images/271180-11d55ece3f57f7eb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
從圖中可以分析得出末誓,使用drawrect方式來實(shí)現(xiàn)圓角扯俱,F(xiàn)PS會(huì)比較高,基本不會(huì)卡頓喇澡。而CPU的使用情況也是可以接受的迅栅。

##3.UIBezierPath,貝塞爾曲線

UIImageView * view = [[UIImageView alloc] init];
view.frame = CGRectMake(200, 0, 44, 44);
[cell addSubview:view];

    UIImage * image = [UIImage imageNamed:@"hehe"];
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(44, 44), NO, 1.0);
    [[UIBezierPath bezierPathWithRoundedRect:view.bounds cornerRadius:22] addClip];
    [image drawInRect:view.bounds];
    view.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();


![bezi.gif](http://upload-images.jianshu.io/upload_images/271180-a5d15b73e4b57ab3.gif?imageMogr2/auto-orient/strip)
![bezi.png](http://upload-images.jianshu.io/upload_images/271180-38282b91f39a912f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
使用貝塞爾曲線來做這個(gè)功能晴玖,CPU使用情況比drawrect的方式要高一些库继,但也沒有很高的狀態(tài)箩艺。

dispatch_queue_t Cricle = dispatch_queue_create("ImageCreate1", NULL);
dispatch_async(Cricle, ^{
UIImage * image = [UIImage imageNamed:@"hehe"];
UIGraphicsBeginImageContextWithOptions(CGSizeMake(44, 44), NO, 1.0);
[[UIBezierPath bezierPathWithRoundedRect:view.bounds cornerRadius:22] addClip];
[image drawInRect:view.bounds];
UIImage * doneImage = UIGraphicsGetImageFromCurrentImageContext();
dispatch_async(dispatch_get_main_queue(), ^{
view.image = doneImage;
});
UIGraphicsEndImageContext();
});

使用一個(gè)子線程去渲染圖片窜醉,然后在主線程更新UI宪萄,這方法在如果只渲染一張圖片速度還是挺快的,cpu和fps都沒啥問題榨惰。但一個(gè)cell中有4個(gè)這樣的圖片拜英,手機(jī)就不行了。
![fps&CPU](http://upload-images.jianshu.io/upload_images/271180-77b8e18503bfe53a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
CPU處于滿載狀態(tài)琅催,一開始fps還有50+居凶,慢慢就變成只有20-30了。所以不推薦這個(gè)藤抡,還是簡(jiǎn)單粗暴比較好侠碧。(若是我打開姿勢(shì)不對(duì),請(qǐng)立馬留意)

##4.Mask缠黍,很有趣的方法

cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
...
...
UIImageView * view = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"hehe"]];
view.frame = CGRectMake(0, 0, 44, 44);
[cell addSubview:view];

    CALayer *maskLayer        = [CALayer layer];
    maskLayer.frame           = view.bounds;
    maskLayer.contents        = (id)[UIImage imageNamed:@"xingxing"].CGImage;
    view.layer.mask = maskLayer;
先看圖
![mask.gif](http://upload-images.jianshu.io/upload_images/271180-aa21dfaac1f5e457.gif?imageMogr2/auto-orient/strip)

![mask.layer.png](http://upload-images.jianshu.io/upload_images/271180-faf1ac28810db2c3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
這實(shí)現(xiàn)效果和layer.cornerRadius相類似弄兜,但Mask的性能比layer.cornerRadius要低。不過優(yōu)點(diǎn)是你可以將你的圖片變成任何形狀的圖形瓷式。

> 總結(jié):
1.如果你的內(nèi)容不多變替饿,并且當(dāng)前頁面不卡頓∶车洌可以使用layer.cornerRadius+ layer.shouldRasterize來實(shí)現(xiàn)视卢。
2.如果你當(dāng)前頁面需要優(yōu)化性能,并且內(nèi)容是變化的廊驼,推薦使用貝塞爾曲線來實(shí)現(xiàn)据过。
3.drawrect方法會(huì)造成離屏渲染,當(dāng)點(diǎn)擊cell或者頁面有內(nèi)容更新的時(shí)候就會(huì)重新調(diào)用妒挎,會(huì)造成不必要的性能損耗绳锅。

ps:有些人會(huì)在圖片上面覆蓋一個(gè)鏤空?qǐng)A形圖片的方法可以實(shí)現(xiàn)圓形頭像效果,這個(gè)雖然是個(gè)極為高效的方法饥漫。但我的想法是——

![你在逗我榨呆!](http://upload-images.jianshu.io/upload_images/271180-1b6b6ab1086f9d6c.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


這里是github連接:
https://github.com/ouzhenxuan/DrawCircle
喜歡請(qǐng)點(diǎn)個(gè)贊。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末庸队,一起剝皮案震驚了整個(gè)濱河市积蜻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌彻消,老刑警劉巖竿拆,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異宾尚,居然都是意外死亡丙笋,警方通過查閱死者的電腦和手機(jī)谢澈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來御板,“玉大人锥忿,你說我怎么就攤上這事〉±撸” “怎么了敬鬓?”我有些...
    開封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)笙各。 經(jīng)常有香客問我钉答,道長(zhǎng),這世上最難降的妖魔是什么杈抢? 我笑而不...
    開封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任数尿,我火速辦了婚禮,結(jié)果婚禮上惶楼,老公的妹妹穿的比我還像新娘右蹦。我一直安慰自己,他們只是感情好鲫懒,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開白布嫩实。 她就那樣靜靜地躺著,像睡著了一般窥岩。 火紅的嫁衣襯著肌膚如雪甲献。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天颂翼,我揣著相機(jī)與錄音晃洒,去河邊找鬼。 笑死朦乏,一個(gè)胖子當(dāng)著我的面吹牛球及,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播呻疹,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼吃引,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了刽锤?” 一聲冷哼從身側(cè)響起镊尺,我...
    開封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎并思,沒想到半個(gè)月后庐氮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宋彼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年弄砍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了仙畦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡音婶,死狀恐怖慨畸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情桃熄,我是刑警寧澤先口,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站瞳收,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏厢汹。R本人自食惡果不足惜螟深,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望烫葬。 院中可真熱鬧界弧,春花似錦、人聲如沸搭综。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽兑巾。三九已至条获,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蒋歌,已是汗流浹背帅掘。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留堂油,地道東北人修档。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像府框,于是被迫代替她去往敵國(guó)和親吱窝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫迫靖、插件院峡、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,124評(píng)論 4 61
  • 轉(zhuǎn)載:http://www.reibang.com/p/32fcadd12108 每個(gè)UIView有一個(gè)伙伴稱為l...
    F麥子閱讀 6,224評(píng)論 0 13
  • 提供了基于Swift3.0模仿的新浪微博的Demo,大家可以下載看一看:基于Swift3.0高仿的微博客戶端,里面...
    skylor閱讀 6,876評(píng)論 7 20
  • 我把月亮丟到天上 路途遙遠(yuǎn) 他瞪了我一眼 所以我丟給他兩顆糖 他還是捂著臉 氣呼呼地瞪 像只松鼠攢著滿腮幫子的...
    阿冰呀閱讀 247評(píng)論 0 0
  • 銀行=安全,銀行存款=穩(wěn)定蜈首,這是大家長(zhǎng)期以來根深蒂固的觀念实抡。但隨著銀行存款進(jìn)入負(fù)利率時(shí)代欠母,銀行理財(cái)逐漸代替銀行存款...
    8846482d58c9閱讀 190評(píng)論 0 0