CFSDN nhấn mạnh vào giá trị tạo ra nguồn mở và chúng tôi cam kết xây dựng nền tảng chia sẻ tài nguyên để mọi nhân viên CNTT có thể tìm thấy thế giới tuyệt vời của bạn tại đây.
Bài viết trên blog CFSDN này tổng hợp các phương pháp triển khai bộ đếm thời gian UITableView trong iOS (NSTimer, DispatchSource, CADisplayLink) được tác giả sưu tầm và biên soạn. Nếu bạn quan tâm đến bài viết này thì nhớ like nhé.
Lời nói đầu.
Gần đây tôi khá bận rộn với công việc nhưng vẫn ra ngoài để cập nhật blog của mình. Nội dung được đề cập trong blog hôm nay không phức tạp. Chúng là một số vấn đề thường gặp. Blog này là bản tóm tắt một số cách sử dụng bộ tính giờ trong uitableview. Blog này sẽ đưa ra năm cách phổ biến để sử dụng nstimer hoặc Dispatssourcer trong chế độ xem bảng. Tất nhiên, phương pháp đầu tiên dưới đây là phương pháp phổ biến nhưng nó cũng là một cạm bẫy khi sử dụng nstimer trong uitableview. Ba cách còn lại là giải pháp vượt qua hố này.
Tất nhiên, blog này bao gồm tổng cộng bốn phương pháp triển khai để sử dụng bộ tính giờ trong uitableview. Tất nhiên, cần có các phương pháp triển khai khác, nhưng cho đến nay tôi vẫn chưa đề cập đến chúng. Bạn có thể cung cấp các phương pháp triển khai khác trong khu vực nhận xét và tôi sẽ sớm tích hợp chúng vào bản demo hiện tại.
Tiếp theo, trước tiên hãy tóm tắt bốn phương pháp liên quan đến blog này:
- Đầu tiên là sử dụng nstimer trực tiếp trên ô xem bảng. Tất nhiên, phương pháp này có vấn đề, sẽ được giới thiệu sau.
- Thứ hai là thêm nstimer vào các mã chung trong runloop tương ứng với luồng hiện tại.
- Phương pháp thứ ba là triển khai bộ hẹn giờ thông qua nguồn hẹn giờ trong công văn.
- Phương pháp thứ tư là bắt đầu một luồng con mới, thêm nstimer vào runloop trong luồng con này và sử dụng các mã defaultrunloopmodes để thực thi.
- Cách thứ năm là sử dụng cadisplaylink.
Dưới đây chúng tôi sẽ giới thiệu chi tiết năm phương pháp triển khai trên dựa trên các ví dụ cụ thể.
1. Sử dụng nstimer trực tiếp trong ô.
Đầu tiên, chúng tôi làm theo thông lệ thông thường và thêm nstimer tương ứng trực tiếp vào ô của uitableview và sử dụng bộ hẹn giờ đã lên lịch để thực thi khối mã tương ứng. Phương pháp này không có gì đặc biệt, đó là việc sử dụng trực tiếp bộ đếm thời gian. Dưới đây là mã sử dụng bộ đếm thời gian trong phần này của chương trình của chúng tôi. Tất nhiên, nó được triển khai bằng Swift, nhưng nó tương tự như mã OC. Mã này như sau:

Đoạn mã trên tương đối đơn giản. Nó thêm bộ đếm thời gian vào ô, cập nhật thời gian mỗi giây và hiển thị nó trên nhãn thời gian của ô. Từ hiệu ứng chạy, chúng ta có thể dễ dàng nhận thấy khi trượt tableview thì bộ đếm thời gian sẽ ngừng hoạt động. Lý do cụ thể là runloop của luồng hiện tại chuyển chế độ mặc định sang chế độ theo dõi vòng lặp khi chế độ xem bảng trượt. Bởi vì bộ đếm thời gian được thêm vào chế độ mặc định trên runloop theo mặc định, bộ hẹn giờ sẽ ngừng chạy khi chế độ này được chuyển.
Nhưng khi dừng trượt thì chế độ sẽ chuyển trở lại nên bộ hẹn giờ có thể hoạt động bình thường.

Để xem xét kỹ hơn về việc chuyển đổi chế độ, chúng ta có thể lấy runloop của luồng hiện tại ở vị trí tương ứng và in chế độ tương ứng. Mã bên dưới được thêm vào vc tương ứng với chế độ xem bảng. Chúng tôi in chế độ hiện tại trong runloop tương ứng với luồng hiện tại trong các phương thức proxy của viewdidload(), viewdidappear() và Scrollviewdidscroll().


Dưới đây là kết quả chạy cuối cùng. Từ kết quả đầu ra, chúng ta có thể dễ dàng nhận thấy chế độ hiện tại được in trong phương thức viewdidload() là uiinitializationrunloopmode. Từ tên của chế độ này, chúng ta có thể dễ dàng nhận thấy chế độ này chịu trách nhiệm khởi tạo ui. Trong phương thức viewdidapperar(), tức là sau khi giao diện người dùng được hiển thị, chế độ runloop được chuyển sang kcfrunloopdefaultmode. Tiếp theo, chúng ta trượt chế độ xem bảng, sau đó in chế độ tương ứng với runloop hiện tại khi trượt trong phương thức proxy Scrollviewdidscroll(). Không khó để nhận thấy từ các kết quả đang chạy bên dưới rằng khi chế độ xem bảng trượt, mô hình hiện tại được in là uitrackingrunloopmode. Khi bạn dừng trượt và nhấp vào nút hiển thị chế độ hiện tại để nhận chế độ hiện tại, đôi khi chế độ mặc định runloop được in. Các chi tiết như sau:

2. Thêm bộ đếm thời gian vào chế độ chung.
Bộ hẹn giờ ở phần trước không thể chạy bình thường vì đối tượng nstimer được thêm vào chế độ mặc định của runloop hiện tại theo mặc định và bộ hẹn giờ sẽ ngừng hoạt động khi nó được chuyển sang chế độ trackrunloop. Cách trực tiếp nhất để giải quyết vấn đề này là thêm nstimer vào chế độ trackrunloop. Trong trường hợp này, bộ hẹn giờ sẽ hoạt động bình thường bất kể ở chế độ mặc định hay chế độ theo dõi.
Nếu các bạn đã quen với runloop thì có thể biết commonmodes là tập hợp của defaultmode và trackrunloopmode nên chúng ta chỉ cần liên kết đối tượng nstimer với các commonmodes trong runloop tương ứng với thread hiện tại.

Sự khác biệt giữa đoạn mã trên và phần đầu tiên của mã là chúng tôi đã thêm bộ hẹn giờ đã tạo vào các mã chung trong vòng lặp chạy hiện tại. Điều này đảm bảo rằng bộ hẹn giờ có thể chạy bình thường khi chế độ xem bảng trượt. Hiệu ứng chạy cuối cùng của đoạn mã trên như sau.

Từ hiệu ứng đang chạy, chúng ta có thể dễ dàng nhận thấy rằng khi chế độ xem bảng đang cuộn, bộ đếm thời gian trên ô của nó có thể hoạt động bình thường. Nhưng khi chúng ta trượt chế độ xem bảng ở góc trên bên phải, bộ đếm thời gian trong chế độ xem bảng đầu tiên không hoạt động chính xác vì các chế độ xem bảng này đều hoạt động trong luồng chính, điều đó có nghĩa là runloop của các chế độ xem bảng này giống nhau.
3. Thêm bộ hẹn giờ vào chế độ mặc định trong runloop của luồng con.
Tiếp theo, chúng ta hãy xem xét một giải pháp khác, đó là bắt đầu một luồng con mới và sau đó thêm bộ đếm thời gian vào runloop tương ứng với luồng con này. Tất nhiên, vì là runloop của thread con nên khi thêm bộ đếm thời gian, chúng ta có thể thêm bộ đếm thời gian vào defaultmode trong runloop của thread con. Sau khi thêm nó, hãy chạy runloop theo cách thủ công.
Vì bộ hẹn giờ được thêm vào trong sub-thread nên bộ hẹn giờ phải hoạt động trong sub-thread nên khi cập nhật UI chúng ta cần cập nhật nó trong main thread.

Trong đoạn mã trên, chúng ta có thể thấy rằng chúng ta sử dụng hàng đợi song song toàn cục để tạo một đối tượng hẹn giờ một cách không đồng bộ, sau đó thêm đối tượng vào defaultrunloopmode trong luồng không đồng bộ, rồi chạy runloop. Tất nhiên, việc cập nhật giao diện người dùng trong luồng con vẫn cần được thực hiện trong luồng chính. Dưới đây là tác dụng của đoạn mã trên. Từ hiệu ứng này, chúng ta có thể dễ dàng nhận thấy bộ đếm thời gian có thể hoạt động bình thường khi trượt tableview.

4、nguồn thời gian điều phối。
Tiếp theo, chúng ta sẽ không sử dụng nstimer để triển khai bộ đếm thời gian. Khi nói về gcd trong blog trước, Clarktimersource đã được sử dụng để triển khai bộ đếm thời gian. Tiếp theo, chúng ta sẽ thêm Clarktimersource vào ô của chế độ xem bảng, sau đó xem hiệu ứng đang chạy. Tất nhiên, trong đoạn mã bên dưới, chúng tôi thêm Clarktimersource vào hàng đợi chung và cập nhật nó trong luồng chính. Tất nhiên, chúng ta cũng có thể thêm Clarktimersource vào hàng đợi chính, nó cũng sẽ hoạt động bình thường. Tất nhiên, chúng tôi không khuyên bạn nên thực hiện nó trong mainqueue, vì khi lập trình, hãy cố gắng đưa một số thao tác không liên quan chặt chẽ đến luồng chính vào các luồng phụ. Mã trông như thế này:

Tiếp theo, chúng ta hãy xem hiệu ứng chạy của đoạn mã trên. Từ hiệu ứng này, chúng ta có thể thấy bộ hẹn giờ có thể hoạt động bình thường.

5、liên kết cadisplay。
Tiếp theo, chúng tôi sử dụng cadisplaylink để triển khai chức năng hẹn giờ. Chúng tôi cũng đã sử dụng cadisplaylink trong blog trước, nhưng nó được sử dụng để tính toán khung hình/giây. Trong đoạn mã bên dưới, chúng tôi sử dụng cadisplaylink để triển khai bộ hẹn giờ. cadisplaylink có thể được thêm vào runloop và mỗi chu kỳ của runloop sẽ kích hoạt phương thức được liên kết với cadisplaylink. Khi màn hình không bị đơ, thời gian mỗi vòng lặp là 1/60 giây.
Mã bên dưới nhằm ngăn chặn việc bộ đếm thời gian không chính xác do chặn runloop tương ứng với luồng chính do màn hình bị treo, v.v. Chúng tôi bắt đầu một luồng mới, thêm đối tượng cadisplaylink vào runloop của luồng phụ này, sau đó cập nhật ui trong luồng chính. Mã cụ thể như sau:

Chúng ta chạy đoạn code trên và bên dưới là kết quả tương ứng. Từ kết quả chạy bên dưới, chúng ta có thể dễ dàng thấy rằng bộ đếm thời gian cũng có thể chạy bình thường khi chế độ xem bảng đang cuộn. Tất nhiên, độ chính xác của bộ đếm thời gian thực hiện theo cách này là tương đối cao.

Sau năm phần trên, chúng tôi đã liệt kê một số phương pháp triển khai bộ tính giờ. Qua so sánh, không khó để tìm ra ưu điểm và nhược điểm của chúng. Độ chính xác của Clarksourcetime và cadisplaylink của các bộ định thời trên cao hơn nstimer. Từ việc triển khai mã, không khó để nhận thấy độ chính xác của cadisplaylink tương đối cao.
Địa chỉ chia sẻ github của mã liên quan đến blog này là: https://github.com/lizelu/ntimerwithrunloop.
Tóm tắt.
Trên đây là toàn bộ nội dung bài viết mong rằng nội dung bài viết có giá trị tham khảo nhất định cho quá trình học tập, làm việc của mọi người. Nếu có thắc mắc gì có thể để lại tin nhắn để trao đổi.
Liên kết gốc: https://www.cnblogs.com/ludashi/p/7349535.html.
Cuối cùng, bài viết này về phần tóm tắt cách triển khai bộ hẹn giờ UITableView trong iOS (NSTimer, DispatchSource, CADisplayLink) sẽ kết thúc tại đây. Nếu bạn muốn biết thêm về bản tóm tắt cách triển khai bộ hẹn giờ UITableView trong iOS (NSTimer, DispatchSource, CADisplayLink). ) ), vui lòng tìm kiếm các bài viết của CFSDN hoặc tiếp tục duyệt các bài viết liên quan. Tôi hy vọng bạn sẽ ủng hộ blog của tôi trong tương lai! .
Tôi là một lập trình viên xuất sắc, rất giỏi!