2017-10-25 17 views
6

Đôi khi tôi thấy một khung nhìn được thực hiện như thế này, trong đó có cùng hàm setup() trong hai phương thức init khác nhau. Sự khác nhau giữa các phương thức init là gì và tại sao cùng một thiết lập() được gọi trong cả hai ..?sự khác biệt giữa init bắt buộc và init bắt buộc? - swift

class BigButton: UIButton { 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     setup() 
    } 

    required init?(coder: NSCoder) { 
     super.init(coder: coder) 
     setup() 
    } 

    fileprivate func setup() { 
     // set up stuff 
    } 
} 
+1

cách đọc [Tài liệu ngôn ngữ Swift] (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18 -XID_335) về khởi tạo? – holex

+0

@holex thế nào về siêu lười biếng – BlueBoy

Trả lời

3

override init(frame: CGRect) được sử dụng khi bạn tạo chế độ xem (trong trường hợp này là nút) theo chương trình.

required init?(coder: NSCoder) được sử dụng khi chế độ xem được tạo từ bảng phân cảnh/xib.

vì sau này là bắt buộc, bạn phải triển khai cơ thể của nó. Tuy nhiên, nếu bạn không tạo nút theo cách thủ công, cái đầu tiên không cần thiết và có thể bị bỏ qua

thiết lập được gọi trong cả hai vì bạn chọn tạo nút bạn muốn thiết lập hành vi tùy chỉnh để nó hoạt động như bạn dự định nó

2

Nếu bạn đang sử dụng lớp như vậy cả trong Interface Builder đâu đó và lập trình một số nơi khác, và các công cụ thiết lập phải được thực hiện không có vấn đề làm thế nào bạn sử dụng lớp, thật dễ dàng để viết init() như thế này.

init(NSCoder:) được gọi tự động khi bạn đặt nút vào .nib hoặc bảng phân cảnh, trình biên dịch biết chính xác khung của chế độ xem sao cho không cần thiết init(CGRect:). Ngược lại, bạn thường sử dụng init(CGRect:) khi tạo chế độ xem bằng mã, bạn muốn đảm bảo rằng setup() được thực hiện trong cả hai quá trình khởi tạo, do đó bạn đặt setup() trong cả hai hàm khởi tạo.

1

Khi bạn override một initializer như init(frame: CGRect), bạn làm điều đó với một initializer định, tức là khởi tạo chủ yếu chịu trách nhiệm cho việc tạo một đối tượng lập trình. Theo quy tắc, bạn phải gọi super.inittrước khi thực hiện bất kỳ hành động init bổ sung nào.

Trình khởi tạo bắt buộc, mặt khác, không giống như được chỉ định.

buộc Initializers

Viết modifier yêu cầu trước khi định nghĩa của một initializer lớp để cho biết rằng mỗi lớp con của lớp phải thực hiện initializer đó.

Bạn cũng phải viết công cụ sửa đổi bắt buộc trước mỗi phân lớp thực hiện trình khởi tạo bắt buộc để cho biết yêu cầu khởi tạo áp dụng cho các lớp con khác trong chuỗi. Bạn không ghi công cụ sửa đổi ghi đè khi ghi đè trình khởi tạo được chỉ định bắt buộc.

Nguồn: Apple Documentation On Initializers

Bạn thực hiện khởi tạo yêu cầu không phụ thuộc ý chí của bạn khi bạn thực hiện một lớp con nếu lớp ban đầu có mà initializer đánh dấu theo yêu cầu. Thông thường, bạn không phải gọi nó trực tiếp để tạo ra một đối tượng, mặc dù trong một số trường hợp bạn làm. Khởi tạo bắt buộc được đánh dấu là bắt buộc để tuân thủ một số yêu cầu. Ví dụ: required init?(coder: NSCoder) được gọi trong nhiều trường hợp. Một trường hợp: khi khung nhìn được tạo từ IB. Một trường hợp khác - khi một đối tượng được tạo ra, hoặc đúng hơn, được hủy lưu trữ (được gọi là deserialization) theo cách thủ công. Trong thực tế, khi bạn đặt đối tượng đó vào chế độ xem của ViewController (ví dụ), đối tượng đó cũng là hủy lưu trữ, tức là tất cả các thuộc tính của nó được tải và đặt. Rõ ràng, khi bạn tạo một lớp con của một số dạng xem, bạn có nghĩa là để làm cho nó hỗ trợ giao diện này, cung cấp khả năng deserialization (trong trường hợp nó đôi khi được sử dụng từ Interface Builder hoặc là một trong hai)). Đây là lý do tại sao nó là required.

Các vấn đề liên quan