เคล็ดลับในการปรับปรุงประสิทธิภาพการเลื่อน UITableView ของ iPhone?


89

ฉันมี uitableview ที่โหลดภาพขนาดใหญ่พอสมควรในแต่ละเซลล์และความสูงของเซลล์จะแตกต่างกันไปขึ้นอยู่กับขนาดของภาพ ประสิทธิภาพการเลื่อนดี แต่บางครั้งอาจกระตุก

ฉันพบเคล็ดลับเหล่านี้ที่พบในบล็อก FieryRobot:

เลื่อนกระจกด้วย uitableview

more-glassy-scrolling-with-uitableview

ใครมีเคล็ดลับในการปรับปรุงประสิทธิภาพการเลื่อน uitableview บ้าง?


หากคุณต้องการแคชความสูงของเซลล์ (ซึ่งอาจมีราคาแพงในการคำนวณและใช้บ่อยด้วย) ฉันได้ยกตัวอย่าง ใช้สิ่งนี้เฉพาะในกรณีที่เหมาะสมกับแอปพลิเคชันของคุณ stackoverflow.com/questions/1371223/…
Paul de Lange

คำตอบ:


156
  1. แคชความสูงของแถว (มุมมองตารางสามารถร้องขอได้บ่อยครั้ง)
  2. สร้างแคชที่ใช้น้อยที่สุดสำหรับรูปภาพที่ใช้ในตาราง (และทำให้รายการที่ไม่ใช้งานทั้งหมดเป็นโมฆะเมื่อคุณได้รับคำเตือนเกี่ยวกับหน่วยความจำ)
  3. วาดทุกอย่างในUITableViewCell's drawRect:ถ้าเป็นไปได้หลีกเลี่ยงการดูย่อยโดยเสียค่าใช้จ่ายทั้งหมด (หรือถ้าคุณต้องการฟังก์ชันการช่วยการเข้าถึงมาตรฐานมุมมองเนื้อหาdrawRect:)
  4. ทำให้UITableViewCellเลเยอร์ของคุณทึบแสง (เช่นเดียวกับมุมมองเนื้อหาหากคุณมี)
  5. ใช้ฟังก์ชัน reusableCellIdentifier ตามที่แนะนำโดยUITableViewตัวอย่าง / เอกสารประกอบ
  6. การไล่ระดับสีหลีกเลี่ยง / ผลกราฟิกที่ซับซ้อนที่ไม่ได้ก่อนอบเป็นUIImages

5
นอกจากนี้ควรลดขนาดรูปภาพที่ดาวน์โหลดลงให้เท่ากับขนาดของ imageView ก่อนที่จะแสดงบนเซลล์!
ZoltánMatók

4
ฉันต้องการเพิ่มคำตอบนี้ให้กับประสบการณ์ของฉันในช่วงสองสามปีที่ผ่านมา - การมีเซลล์โปร่งใสอาจไม่เป็นสาเหตุของประสิทธิภาพการเลื่อนที่ไม่ดี เรามีแอปที่มีเซลล์ที่ซับซ้อนมาก (20+ subviews) และทุกอย่างโปร่งใสเพื่อแสดงพื้นหลัง ด้วยการเพิ่มประสิทธิภาพที่เหมาะสมความโปร่งใสจะไม่แตกต่างแม้แต่กับ 3GS จริงๆแล้วสิ่งที่ทำให้สิ่งต่างๆช้าลงมากที่สุดคือการโหลดปลายปากกาก่อนที่จะมีเซลล์เพียงพอที่จะยกเลิกคิวจากมุมมองตาราง หากใช้มุมมองย่อยตรวจสอบให้แน่ใจว่ามีลำดับชั้นที่มีประสิทธิภาพและคุณไม่จำเป็นต้องใช้ drawRect
Accatyyc

@Accatyyc ดูเหมือนว่าฉันจะมีปัญหาเดียวกัน มีความล่าช้าเล็กน้อยเมื่อมีเซลล์ไม่เพียงพอที่จะออกคิวเมื่อ 3-4 เซลล์ถูกยกเลิกการจัดคิวการเลื่อนจะราบรื่น มีวิธีใดในการโหลดเซลล์ล่วงหน้าเพื่อให้มีเซลล์ที่จะยกเลิกคิวและไม่โหลดไฟล์ NIB เมื่อเลื่อน
Tiois

@Tiois ชัวร์มี. คุณต้องใช้วิธีการยกเลิกคิวเซลล์แบบเก่า (อย่าลงทะเบียนคลาส / ปลายปากกา แต่สร้างถ้า dequeueCellWithIdentifier: คืนค่าศูนย์) ด้วยวิธีนี้คุณสามารถสร้างชุดของเซลล์ก่อนที่มุมมองตารางของคุณจะมีอยู่เช่นสร้างเซลล์ 20 เซลล์ขึ้นมาก่อน จากนั้นแทนที่จะสร้างใหม่ใน cellForRowAtIndexPath: คุณดึงออกจากแคชของคุณเองก่อนจนกว่าจะว่างเปล่า
Accatyyc

ฉันใช้ UICollectionView และประสบปัญหาเดียวกัน ในไฟล์ nib เซลล์ที่กำหนดเองของฉัน ฉันใช้มุมมองย่อยหลายรายการรวมถึง UIwebView และ UIImageView ภายใน UIstackView แนวตั้ง เมื่อฉันเลื่อนรายการของฉันเซลล์ที่นำกลับมาใช้ใหม่ต้องใช้เวลาพอสมควรในการปรับขนาดใหม่และการเลื่อนดูกระตุกมาก
มันซู ....

40
  1. หากคุณเป็นคลาสย่อย UITableViewCellอย่าใช้ Nib เขียนเป็นรหัสแทน เร็วกว่าการโหลดไฟล์ Nib มาก
  2. หากคุณกำลังใช้รูปภาพตรวจสอบให้แน่ใจว่าคุณกำลังแคชอยู่เพื่อที่คุณจะได้ไม่ต้องโหลดจากไฟล์มากกว่าหนึ่งครั้งสำหรับแต่ละไฟล์ (หากคุณมีหน่วยความจำคุณจะแปลกใจว่ารูปภาพนั้นใช้พื้นที่มากแค่ไหน)
  3. ทำให้องค์ประกอบทึบแสงให้มากที่สุด ในทำนองเดียวกันพยายามอย่าใช้รูปภาพอย่างโปร่งใส

3
ไม่ต้องกังวล ... นั่นคือโทรลล์ คำตอบที่ดี!
Steav

79
คะแนนที่ลดลงอาจเป็นเพราะ "หลีกเลี่ยงการกัด" เป็นคำแนะนำที่ไม่ดีในการปรับปรุงประสิทธิภาพ หากคุณนำเซลล์กลับมาใช้ใหม่เซลล์จะไม่ถูกสร้างขึ้นใหม่จากปลายปากกาเลยเมื่อเลื่อน
Steven Fisher

6
ปลายปากกามีความเร็วเทียบเท่าหรือเร็วกว่าเล็กน้อยจากการวิจัยของ Cocoa with Love cocoawithlove.com/2010/03/…
MaxGabriel

@Steven Fisher โดยใช้ Nib อาจช้าลงเมื่อตารางจัดสรรและ deallocs เซลล์ตัวอย่างเช่นในระหว่างการเลื่อนอย่างรวดเร็ว
Sound Blaster

3
ใช้ไส้อาจจะช้ากว่าเมื่อเซลล์จะถูกสร้างขึ้น หากคุณกำลังใช้การรีไซเคิลเซลล์จะมีเซลล์ที่จัดสรรให้เต็มหน้าจอเท่านั้น พูดว่าอาจจะมากที่สุด 10 เมื่อคุณกำลังเลื่อนเซลล์จะไม่ถูกสร้างขึ้น พวกเขาเพิ่งนำกลับมาใช้ใหม่ไม่ได้ถูกจัดสรรและจัดสรรใหม่ และแน่นอนว่าไม่มีค่าใช้จ่ายในการ dealloc ไม่นี่ไม่ถูกต้อง
Steven Fisher

34

ผู้พัฒนาที่อยู่เบื้องหลัง Tweetie ได้เขียนเกี่ยวกับเรื่องนี้อย่างกว้างขวางและมีโค้ดบางอย่างที่แสดงให้เห็นว่ามันทำอย่างไรกับแอพนั้น โดยทั่วไปเขา / เธอสนับสนุนมุมมองที่กำหนดเองหนึ่งมุมมองต่อเซลล์ตารางและวาดด้วยตนเอง (แทนที่จะดูย่อยด้วยตัวสร้างอินเทอร์เฟซรวมถึงตัวเลือกอื่น ๆ )

เลื่อนอย่างรวดเร็วในทวีตตีด้วย uitableview

นอกจากนี้ Apple ได้อัปเดตโค้ดตัวอย่างของตัวเองสำหรับ TableView ในบทช่วยสอน TableViewSuite (อาจตอบสนองต่อสิ่งนี้)

TableViewSuite


1
นี่เป็นทางออกที่ยอดเยี่ยม ฉันแค่อยากรู้ว่าฉันจะเพิ่ม UIButton ลงใน cellView ได้อย่างไร มันถูกวาดด้วยเมธอด drawRect หรือไม่?
Sukitha Udugamasooriya

1
@beno ลิงค์ของคุณดูเหมือนจะเสีย (อันแรก) มีโอกาสที่จะวางมือจากบทความต้นฉบับหรือไม่?
apouche

3
สามารถอ่านบทความต้นฉบับได้ที่นี่: web.archive.org/web/20100922230053/http://blog.atebits.com/2008/…
jverdi

เพิ่มลิงก์ไปยังที่เก็บถาวรของเว็บเนื่องจากไม่มีเวอร์ชันดั้งเดิม
Ralph Willgoss

1

นักฆ่าประสิทธิภาพอันดับ 1 สำหรับการเลื่อน UITableView คือการวาดเงาบนเลเยอร์มุมมองเซลล์ใด ๆ ดังนั้นหากประสิทธิภาพการเลื่อนมีความสำคัญอย่าทำเงาเว้นแต่โดยพื้นฐานแล้วมันจะไม่ทำให้เธรดหลักของคุณช้าลง

คิดว่าจะต้องพูดถึงเรื่องนี้เนื่องจากไม่มีคำตอบใดที่ยอมรับได้กล่าวถึงเงาและเลเยอร์ : +)


6
หากปัญหาคือเงาให้เพิ่มโค้ดสองบรรทัดนี้และทั้งหมดทำงานได้อย่างสมบูรณ์ self.layer.shouldRasterize = ใช่; self.layer.rasterizationScale = UIScreen.mainScreen.scale;
Pedro Romão

0

ปัญหาใด ๆ เกี่ยวกับUITableViewประสิทธิภาพการเลื่อนสามารถแก้ไขได้โดยใช้เทคนิคที่อธิบายไว้แล้วในคำตอบอื่น ๆ อย่างไรก็ตามหลายครั้งที่ประสิทธิภาพการทำงานที่ซบเซาเกิดจากสิ่งที่ผิดพลาดโดยเนื้อแท้หรือซ้ำซาก

ความจริงที่ว่าUITableViewนำเซลล์กลับมาใช้ใหม่และความจริงที่ว่าแต่ละเซลล์อาจต้องการภาพของตัวเองร่วมกันทำให้การแก้ปัญหามีความซับซ้อนเล็กน้อย จากวิธีการแก้ไขโดยทั่วไปฉันสรุปสิ่งที่ควรดูแล:

  1. โหลดข้อมูลลงในแหล่งข้อมูล - จาก REST / ฐานข้อมูล ขั้นตอนนี้ควรทำในพื้นหลังโดยใช้ dispatch_async ร่วมกับคิว GCD ในที่สุด
  2. สร้างและเริ่มต้นอ็อบเจ็กต์โมเดลข้อมูลที่เกี่ยวข้องและวางไว้ในอาร์เรย์
  3. [tableView reloaddata]
  4. ข้างใน cellForRowAtIndexPathรวมรหัสที่จะตั้งค่าข้อมูล (ข้อความ) จากวัตถุโมเดลข้อมูลที่ถูกต้องของอาร์เรย์
  5. ตอนนี้รูปภาพอาจอยู่ในรูปแบบของ URL เช่นกันดังนั้นขั้นตอนนี้อาจดูแปลก ๆ เล็กน้อยเนื่องจากการใช้เซลล์ซ้ำโดยมุมมองตาราง หัวใจสำคัญของความจริงคือการโหลดรูปภาพอีกครั้งจากแคช / URL ของอุปกรณ์โดยใช้คิว async จากนั้นตั้งค่าให้แก้ไข cell.image (คุณสมบัติรูปภาพเซลล์ของคุณคืออะไร)

เพื่อหลีกเลี่ยงปัญหาโปรดดูบทช่วยสอนนี้เกี่ยวกับการโหลดรูปภาพภายในมุมมองตาราง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.