Những gì bạn cần biết về tổng hợp tài sản tự động

Trong các bản phát hành gần đây nhất của XCode, Apple đã thực hiện một số cải tiến thú vị về cách trình biên dịch LLVM xử lý các thuộc tính được khai báo. Những cải tiến này đã dẫn đến những thay đổi có thể nhìn thấy đối với cách các thuộc tính hiện xuất hiện trong các mẫu dự án, mã được tạo tự động bởi IDE và trong mã mẫu của Apple, một số trong đó hiện có thể đang kiểm tra sự hiểu biết của bạn về các thuộc tính và cách chúng thực sự hoạt động. Vì vậy, trước khi chỉ mù quáng nhảy vào và sử dụng các thuộc tính được tổng hợp tự động, đáng để dành một chút thời gian để hiểu chính xác những gì đang diễn ra dưới vỏ bọc.

Thuộc tính so với biến Instance

Đầu tiên và quan trọng nhất, các thuộc tính không giống như các biến thể hiện ( ivars) . Các biến sơ thẩm chứa thông tin về các thuộc tính khác nhau của một đối tượng, chẳng hạn như tên hoặc điểm của người chơi trong ứng dụng trò chơi. Các thuộc tính thường được hỗ trợ bởi ivars, mặc dù chúng không phải như vậy.

Khi bạn khai báo một thuộc tính, về cơ bản, bạn đang khai báo các phương thức truy cập, được sử dụng để đặt và truy xuất (lấy) giá trị của thuộc tính. Thông thường bạn sử dụng câu lệnh @synthesize để báo cho trình biên dịch tự động tạo các phương thức này, nhưng bạn cũng có thể tự viết chúng khi muốn có hành vi rất cụ thể. Do đó, điều rất quan trọng để giữ sự khác biệt giữa các thuộc tính và ngà trong tâm trí của bạn.

Để minh họa, nhiều sách và hướng dẫn bắt đầu trên iOS thường hiển thị một cái gì đó như thế này trong tệp tiêu đề (.h):

Mã này được theo sau trong tệp triển khai (.m):

Điều không rõ ràng ngay lập tức đối với lập trình viên iOS mới là playerName vừa là tên của một chiếc ngà trong định nghĩa giao diện vừa là tên của thuộc tính được khai báo trong câu lệnh @property, nhưng chúng không giống nhau . Vì cả tên và loại xảy ra trùng khớp, trình biên dịch sẽ tự động gán ivar để sao lưu thuộc tính khi nó tổng hợp các phương thức truy cập, trông giống như thế này (trong những ngày trước ARC):

Chúng tôi thậm chí có thể sử dụng XCode để quan sát sự khác biệt. Nếu chúng ta xem câu lệnh @synthesize, XCode cho thấy playerName là một thuộc tính:

Nhưng trong phương thức setter, chúng ta thấy rằng đó là một chiếc ngà:

Nói chung, trừ khi bạn có lý do rất cụ thể để không làm như vậy, nên truy cập ivars bằng phương thức thuộc tính của họ chứ không phải trực tiếp để bất kỳ logic đặc biệt nào, chẳng hạn như kiểm tra giới hạn, v.v. Một thuộc tính setter có thể thực hiện logic tùy chỉnh khác ngoài việc thay đổi giá trị của ivar. Nhưng nếu cả ivar và tài sản có cùng tên, làm thế nào để bạn xác định cái nào bạn đang tham khảo?

Đây là nơi mà từ khóa tự phát huy tác dụng. Bằng cách thêm tiền tố playerName với chính mình. bạn sẽ truy cập vào tài sản; không có nó bạn sẽ trực tiếp tham khảo ivar.

Điều này có vẻ không quan trọng, nhưng giả sử bạn có một phương thức getter thực hiện xử lý đặc biệt như sau:

Cấp độ kỹ năng của người chơi sẽ xác định một loạt kẻ thù sẽ chiến đấu. Hãy xem điều gì xảy ra khi chúng ta chạy đoạn mã sau:

Chúng tôi nhận được kết quả như sau:

Câu lệnh NSLog đầu tiên tham chiếu trực tiếp đến ivArArArAr. Các lập trình viên iOS mới có thể hy vọng điều này sẽ trả về giá trị là 2, tuy nhiên tại thời điểm này, kẻ thù chưa được khởi tạo và không có, vì vậy việc gửi tin nhắn đếm tới nó có kết quả là 0 và dường như chúng ta không có kẻ thù để chiến đấu.

Vì câu lệnh NSLog thứ hai tham chiếu thuộc tính self.enemyArray, nên phương thức accessor được gọi để khởi tạo giá trị của ivArArArAr. Bây giờ khi chúng ta tham chiếu trực tiếp ivar trong câu lệnh NSLog thứ ba, chúng ta sẽ nhận được giá trị mà chúng ta đang mong đợi.

Điều đáng nói là nếu bạn không cẩn thận truy cập ivars thông qua các thuộc tính của chúng, bạn có thể nhận được kết quả không mong muốn và đưa ra các lỗi tinh vi có thể khó theo dõi sau này.

Một cách tốt hơn

Một trong những cải tiến gần đây trong XCode là tập trung vào việc sử dụng ký tự gạch dưới làm quy ước để đặt tên các biến thể hiện. Mục tiêu là để thúc đẩy khả năng đọc mã trong khi giúp tránh nhầm lẫn khi vô tình truy cập vào một biến thể hiện thay vì thuộc tính của nó. Về mặt kỹ thuật, điều này là có thể trước khi Apple chính thức thực hiện chuyển đổi trong tài liệu của mình, nhưng với XCode 4.4, nó đã trở thành cách được ưa thích và hiện diện rõ ràng hơn nhiều. Sử dụng quy ước này, mã tiêu đề của chúng tôi bây giờ trông như thế này:

Và mã thực hiện của chúng tôi trông như thế này:

Việc sử dụng dấu gạch dưới bây giờ làm cho nó khá rõ ràng khi biến đối tượng đang được tham chiếu. Có nhiều thứ này bây giờ dưới vành đai của chúng tôi, bây giờ chúng tôi có thể đánh giá cao và hiểu được sự tổng hợp tự động của các thuộc tính.

Với tổng hợp tự động, không còn cần thiết phải tuyên bố cụ thể sao lưu ngà hoặc viết câu lệnh @synthesize. Khi trình biên dịch tìm thấy một câu lệnh @property, nó sẽ thay mặt chúng tôi sử dụng các hướng dẫn mà chúng tôi vừa xem xét. Vì vậy, tất cả những gì chúng ta cần làm là khai báo một tài sản như thế này:

Và trình biên dịch sẽ tự động khai báo một ivar có tên _playerName và thực thi câu lệnh @synthesize để liên kết chúng lại với nhau như sau:

Cả tuyên bố của ivar hoặc câu lệnh tổng hợp sẽ xuất hiện trong mã của bạn; nó chỉ đơn giản được thêm vào trong thời gian biên dịch.

Kết quả

Đó là tất cả để hiểu tổng hợp tự động. Mặc dù có vẻ như không phải là vấn đề lớn, nhưng kết quả cuối cùng là phần lớn mã hóa trần tục mà chúng ta thường làm khi thiết lập ngà voi và các thuộc tính giờ đây có thể được loại bỏ hoàn toàn. Chúng ta có thể khai báo các thuộc tính trong một tuyên bố đơn giản và tiếp tục! Và vì bây giờ bạn đã hiểu những gì đang diễn ra đằng sau hậu trường, bạn có thể tự tin làm điều đó.

Cũng đọc:

  • Năm cuốn sách mà mọi nhà phát triển Apple iOS nên sở hữu
  • Tạo ứng dụng đồng hồ Apple iPhone của riêng bạn
  • Apple cho phép các nhà phát triển ứng dụng tiếp tục theo dõi với iOS 6

© Copyright 2021 | pepebotifarra.com