Thủ thuật để cải thiện hiệu suất cuộn UITableView của iPhone?


89

Tôi có một chế độ xem không phù hợp tải hình ảnh khá lớn trong mỗi ô và chiều cao ô thay đổi tùy thuộc vào kích thước của hình ảnh. Hiệu suất cuộn ở mức khá, nhưng đôi khi có thể bị giật.

Tôi đã tìm thấy những mẹo này mà tôi đã tìm thấy trên blog FieryRobot:

Glassy-scrolling-with-uitableview

more-glassy-scrolling-with-uitableview

Có ai có bất kỳ mẹo nào để cải thiện hiệu suất cuộn uitableview không?


Nếu bạn cần cache chiều cao ô (có thể tốn kém để tính toán và cũng được sử dụng thường xuyên), tôi đã đưa ra một ví dụ. Chỉ sử dụng điều này nếu nó phù hợp trong ứng dụng của bạn. stackoverflow.com/questions/1371223/…
Paul de Lange

Câu trả lời:


156
  1. Lưu vào bộ nhớ cache chiều cao của các hàng (chế độ xem bảng có thể yêu cầu điều này thường xuyên)
  2. Tạo bộ đệm ẩn ít được sử dụng nhất cho các hình ảnh được sử dụng trong bảng (và làm mất hiệu lực của tất cả các mục không hoạt động khi bạn nhận được cảnh báo bộ nhớ)
  3. Vẽ mọi thứ trong UITableViewCell's drawRect:nếu có thể, tránh các lần xem phụ bằng mọi giá (hoặc nếu bạn yêu cầu chức năng trợ năng tiêu chuẩn, chế độ xem nội dung của drawRect:)
  4. Làm cho UITableViewCelllớp của bạn trở nên mờ đục (tương tự đối với chế độ xem nội dung nếu bạn có)
  5. Sử dụng chức năng ReusableCellIdentifier theo khuyến nghị của các UITableViewví dụ / tài liệu
  6. Tránh các hiệu ứng chuyển sắc / đồ họa phức tạp không được tạo sẵn trong UIImages

5
Ngoài ra, các hình ảnh đã tải xuống phải được thu nhỏ xuống kích thước của imageView trước khi hiển thị trên ô!
Zoltán Matók

4
Tôi muốn thêm vào câu trả lời này một kinh nghiệm của tôi trong vài năm qua - có các ô trong suốt có lẽ không bao giờ là nguyên nhân gây ra hiệu suất cuộn kém. Chúng tôi có một ứng dụng với RẤT phức tạp (20+ lượt xem phụ) và tất cả đều trong suốt để hiển thị nền. Với những tối ưu hóa phù hợp, độ trong suốt không có gì khác biệt ngay cả trên 3GS. Trên thực tế, điều làm chậm mọi thứ nhất là tải ngòi trước khi có đủ ô để xếp hàng từ chế độ xem bảng. Nếu sử dụng chế độ xem phụ, chỉ cần đảm bảo có cấu trúc phân cấp hiệu quả và bạn không cần sử dụng drawRect.
Accatyyc

@Accatyyc, có vẻ như tôi cũng gặp vấn đề tương tự. Có một độ trễ nhỏ khi không có đủ ô để khử hóa chất, khi 3-4 ô được khử hóa chất thì quá trình cuộn trơn tru. Có cách nào để tải trước ô để có ô để xếp hàng và không tải tệp NIB khi cuộn không?
Tiois

@Tiois Chắc chắn là có. Bạn cần sử dụng cách cũ để định vị ô (không đăng ký các lớp / nibs, nhưng hãy tạo chúng nếu dequeueCellWithIdentifier: trả về nil). Bằng cách này, bạn có thể tạo một tập hợp các ô trước khi chế độ xem bảng của bạn tồn tại, ví dụ: tạo 20 ô trong số chúng trước đó. Sau đó, thay vì tạo những cái mới trong cellForRowAtIndexPath :, bạn kéo chúng từ bộ nhớ cache của riêng mình trước, cho đến khi nó trống.
Accatyyc

Tôi đang sử dụng UICollectionView và gặp phải vấn đề tương tự. Trong tệp nib ô tùy chỉnh của tôi. Tôi đang sử dụng một số chế độ xem phụ bao gồm UIwebView và UIImageView bên trong UIstackView dọc. khi tôi cuộn danh sách của mình, các ô được sử dụng lại sẽ mất thời gian đáng kể để điều chỉnh lại kích thước của chúng và việc cuộn trông rất giật.
Mansuu ....

40
  1. Nếu bạn đang phân lớp UITableViewCell , không sử dụng Nib, thay vào đó hãy viết nó bằng mã. Nó nhanh hơn nhiều so với tải tệp Nib.
  2. Nếu bạn đang sử dụng hình ảnh, hãy đảm bảo rằng bạn đang lưu vào bộ nhớ đệm để không phải tải từ tệp nhiều lần cho mỗi tệp (nếu bạn có bộ nhớ - bạn sẽ ngạc nhiên khi hình ảnh chiếm bao nhiêu dung lượng).
  3. Làm cho càng nhiều yếu tố càng mờ càng tốt. Tương tự, không thử và sử dụng hình ảnh có độ trong suốt.

3
đừng lo lắng ... đó là troll. câu trả lời chính xác!
Steav 29/10/10

79
Số phiếu giảm có thể là do "tránh ngòi" là lời khuyên tồi để cải thiện hiệu suất. Nếu bạn đang sử dụng lại các ô, các ô sẽ không được tái tạo lại từ ngòi khi cuộn.
Steven Fisher

6
Các ngòi có tốc độ tương đương hoặc nhanh hơn một chút dựa trên nghiên cứu về Cocoa with Love. cocoawithlove.com/2010/03/…
MaxGabriel

@Steven Fisher sử dụng Nib có thể chậm hơn khi phân bổ bảng và ô deallocs, chẳng hạn - trong khi cuộn nhanh.
Sound Blaster

3
Sử dụng NIB thể chậm hơn khi ô đang được xây dựng . Nếu bạn đang sử dụng tái chế ô, chỉ có đủ ô được phân bổ để lấp đầy màn hình; nói, có thể nhiều nhất là 10. Khi bạn đang cuộn, các ô không được tạo. Chúng chỉ được tái sử dụng , không được phân bổ và phân bổ lại. Và, tất nhiên, không có chi phí để thỏa thuận. Vì vậy, không, điều này không chính xác.
Steven Fisher

34

Nhà phát triển đằng sau Tweetie đã viết rất nhiều về điều này và có một số mã minh họa cách nó được thực hiện cho ứng dụng đó. Về cơ bản, anh ấy / cô ấy ủng hộ một chế độ xem tùy chỉnh trên mỗi ô bảng và vẽ nó theo cách thủ công (thay vì xem xét phụ với Trình tạo giao diện, trong số các tùy chọn khác).

nhanh-cuộn-trong-tweetie-with-uitableview

Ngoài ra, Apple đã cập nhật mã mẫu của riêng mình cho TableView trong hướng dẫn TableViewSuite của mình (có thể để đáp ứng điều này?)

TableViewSuite


1
Đây là một giải pháp tuyệt vời. Tôi chỉ tò mò làm cách nào để thêm UIButton vào cellView? Nó có được vẽ trong phương thức drawRect không?
Sukitha Udugamasooriya,

1
@beno, liên kết của bạn có vẻ bị hỏng (liên kết đầu tiên) bất kỳ cơ hội nào để chúng tôi đặt tay vào bài viết gốc?
apouche

3
Các bài viết gốc có thể được đọc ở đây: web.archive.org/web/20100922230053/http://blog.atebits.com/2008/...
jverdi

thêm liên kết đến kho lưu trữ web như phiên bản gốc không tồn tại
Ralph Willgoss

1

Sát thủ hiệu suất số 1 đối với cuộn UITableView là vẽ bóng trên bất kỳ lớp xem ô nào, vì vậy nếu hiệu suất cuộn quan trọng thì đừng tạo bóng trừ khi về cơ bản nó không làm chậm luồng chính của bạn.

nghĩ rằng điều này phải được nói vì không có câu trả lời được chấp nhận nào đề cập đến bóng và các lớp. : +)


6
nếu các vấn đề là bóng đổ, hãy thêm hai dòng mã này và tất cả đều hoạt động hoàn hảo self.layer.shouldRasterize = YES; self.layer.rasterizationScale = UIScreen.mainScreen.scale;
Pedro Romão

0

Bất kỳ vấn đề nào với UITableViewhiệu suất cuộn đều có thể được giải quyết bằng cách sử dụng các kỹ thuật đã được mô tả trong các câu trả lời khác. Tuy nhiên, đôi khi hiệu suất chậm chạp là do một cái gì đó vốn có sai sót hoặc lặp đi lặp lại.

Thực tế là UITableViewsử dụng lại các ô và thực tế là mỗi ô có thể cần hình ảnh riêng của nó - cùng nhau làm cho giải pháp trở nên phức tạp. Từ cách nó được giải quyết theo cách chung, ở đây tôi tóm tắt những điều cần lưu ý:

  1. Nạp dữ liệu vào nguồn dữ liệu - từ REST / cơ sở dữ liệu. Bước này nên được thực hiện ở chế độ nền, cuối cùng sử dụng Dispatch_async cùng với hàng đợi GCD.
  2. Tạo và khởi tạo các đối tượng mô hình dữ liệu có liên quan và đưa chúng vào bên trong một mảng
  3. [tableView reloaddata]
  4. Bên trong cellForRowAtIndexPath, bao gồm mã sẽ thiết lập dữ liệu (văn bản) từ đối tượng mô hình dữ liệu chính xác của mảng.
  5. Bây giờ hình ảnh cũng có thể ở dạng URL, vì vậy bước này có thể hơi kỳ quặc vì việc sử dụng lại ô được thực hiện bởi chế độ xem bảng. Trung tâm của thực tế là tải một lần nữa hình ảnh từ bộ nhớ cache / URL của thiết bị bằng cách sử dụng hàng đợi không đồng bộ, sau đó đặt nó thành đúng cell.image (bất kể thuộc tính hình ảnh ô của bạn là gì).

Để tránh sự cố, hãy tham khảo hướng dẫn này về cách tải hình ảnh trong chế độ xem bảng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.