2016-07-20 21 views
5

Tôi đang cố gắng hiểu cách thức hoạt động của tính năng lười biếng nhanh chóng. Mã sau đây biên dịch mà không có bất kỳ lỗi nào.Lỗi biên dịch khi sử dụng biến số lười

import UIKit 
class Test : UIViewController{ 
    let i = 1 
    lazy var j:Int = self.i 
} 

Trong khi đó nếu tôi loại bỏ các loại j và làm cho nó suy ra như mã dưới đây,

import UIKit 
class Test : UIViewController{ 
    let i = 1 
    lazy var j = self.i 
} 

tôi nhận được lỗi biên dịch "Giá trị của loại 'NSObject ->() -> Test' có không có thành viên 'i' "

Ai đó có thể giải thích những gì đang diễn ra với trình biên dịch. Cảm ơn

Trả lời

4

Bạn cần cân nhắc 3 khía cạnh tại đây.

  • Thuộc tính được lưu trữ lười là thuộc tính có giá trị ban đầu là được tính cho đến lần đầu tiên được sử dụng. Đó là khi bạn gọi thuộc tính lần đầu tiên giá trị của nó sẽ được tính.
  • Khi giá trị thực tế được tạo ra bằng cách đánh giá, bạn cần khai báo kiểu dữ liệu của biến lười biếng ở phía trước.
  • Các thuộc tính bạn khai báo trong lớp là các biến cá thể, nếu bạn cần truy cập các giá trị của chúng, bạn cần một đối tượng (đối tượng) là lớp.

Chúng ta hãy xem xét sau dòng từ mã làm việc phi bạn

lazy var j = self.i 

Hai vấn đề được trình bày trong mã làm việc phi bạn. Đầu tiên là bạn chưa chỉ định kiểu dữ liệu của biến lười. Khi khai báo là trình biên dịch không đầy đủ sẽ không xử lý 'j' như là var lười, nó sẽ coi là biến bình thường. Bạn phải biết về quy tắc của swift rằng bất cứ khi nào bạn khai báo bất kỳ biến nào trong lớp, bạn phải gán một số giá trị cho nó hoặc nếu không bạn có thể biến biến đó thành tùy chọn. Trong câu lệnh trên bạn đang cố gắng gán giá trị của i cho j bằng cách sử dụng self trong lớp. Khi trình biên dịch biên dịch dòng không có đối tượng của lớp được tạo và tự bạn đang sử dụng là nil, đó là lý do tại sao trình biên dịch ném lỗi (Nó sẽ ném lỗi ngay cả khi bạn không sử dụng tự do cùng một lý do được đề cập ở trên) .

Tại sao nó không được gây ra vấn đề trong mã làm việc của bạn:

lazy var j:Int = self.i 

Như tôi đã đề cập ở trên các giá trị cho var lười biếng được chỉ định khi bạn gọi biến đó. Bạn sẽ gọi biến đó ra ngoài lớp như thế nào? Tất nhiên bằng cách tạo đối tượng. Và khi bạn sẽ gọi nó với sự giúp đỡ của đối tượng 'tự' sẽ chỉ vào cùng một đối tượng và bản thân sẽ không được nil nó sẽ không gây ra bất kỳ vấn đề gì.

Trong hai điều ngắn bạn cần phải hiểu 3 điều

  • Trong khi tuyên bố var lười biếng bạn phải xác định kiểu dữ liệu
  • var lười biếng không được phân định khi nó được công bố, nó được chỉ định khi nó được gọi là
  • bạn không thể gọi dụ var mà không dụ (đối tượng) của lớp
+0

Tôi không nghĩ rằng kiểu dữ liệu là cần thiết khi khai báo var lười biếng. Mã "lazy var name =" một số tên "' biên dịch mà không có bất kỳ vấn đề –

+2

Nếu bạn đang đi qua bất kỳ giá trị hardcoded để lười var nó không yêu cầu trình biên dịch kiểu dữ liệu sẽ hiểu loại đó là lý do tại sao lười biếng var name = "some name" đang làm việc. Trong mã của bạn, bạn không gán giá trị trực tiếp, bạn đang cố gắng gán giá trị của tôi với sự giúp đỡ của bản thân. Ở đây trình biên dịch không biết về kiểu dữ liệu tự, i và i. Đó là lý do tại sao kiểu dữ liệu được yêu cầu trong các trường hợp như vậy cũng như trong trường hợp bạn đang viết đóng của bạn lười var. –

0

Dưới đây là một ví dụ về khởi tạo lười biếng với một điều khiển xem Ler

Lưu ý() vào cuối

lazy var myViewController : MyViewController? = { 
    let storyboard: UIStoryboard = UIStoryboard(name: "MyVC", bundle: nil) 
    return storyboard.instantiateViewController(withIdentifier: "MyAccount") as? MyViewController 
}() 
Các vấn đề liên quan