2017-05-08 15 views
5

Tôi đã tìm thấy vấn đề đích UIBarButtonItem này một cách vô ý thức khi sử dụng khởi tạo var lười biếng.iOS lazy var UIBarButtonItem target issue

class ViewController: UIViewController { 
    lazy var barButtonItem1 = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(action1)) 
    lazy var barButtonItem2: UIBarButtonItem = { 
    let barButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(action2)) 
    return barButtonItem 
    } 

    override func viewDidLoad() { 
    super.viewDidLoad() 

    print(barButtonItem1.target, barButtonItem2.target) 
    } 
} 

Kết quả in cho thấy rằng barButtonItem1.target là nil và barButtonItem2.target là tự, điều này có vẻ điên rồ! Tôi nhận được vấn đề này khi tôi sử dụng văn bản lười biếng var barButtonItem1, và sau đó tôi thấy rằng hành động của barButtonItem1 không bao giờ có thể được gọi, và cuối cùng vấn đề là barButtonItem1.target là nil.

Tôi không biết tại sao điều này xảy ra, tuy nhiên tôi chắc chắn đây là lỗi. Có ai biết gì về điều này không? Tôi sẽ thực sự đánh giá cao nếu bạn có thể giải thích về nó.

+1

Tôi không nghĩ rằng bạn đang làm 'barButtonItem1' một cách chính xác. Đầu tiên 'lazy var' phải được khai báo với kiểu dữ liệu. Thứ hai, bạn chỉ cần thiết lập giá trị của nó giống như một var thông thường. Vui lòng đọc: https: //www.hackingwithswift.com/example-code/language/what-are-lazy-variables – thedp

+0

Tuyên bố của barButtonItem1 phải chính xác, theo [link] (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language /Properties.html). – user5685969

+1

Theo [link] (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html), khai báo của barButtonItem1 phải chính xác. Tuy nhiên tôi đã thử những gì bạn nói để thêm một khai báo kiểu dữ liệu cho barButtonItem1, và nó hoạt động tốt ngay bây giờ. Tôi vẫn không biết điều gì gây ra điều này. – user5685969

Trả lời

3

Giải thích bên dưới là dự đoán của tôi. Và thật không may, tôi không có đủ danh tiếng để đưa ra nhận xét vì vậy hãy để tôi trả lời bạn.

Đoán của tôi: đây là lỗi trình biên dịch.


Trước tiên, tôi đã tạo một phần mở rộng nhỏ của UIBarButtonItem. (Tham số thứ hai không phải là của Any? nhưng UIViewController?)

extension UIBarButtonItem { 
    convenience init(barButtonSystemItem systemItem: UIBarButtonSystemItem, targetViewController: UIViewController?, action: Selector?) { 
     // call the initializer provided by UIKit 
     self.init(barButtonSystemItem: systemItem, target: targetViewController, action: action) 
    } 
} 

Sau đó, tôi đã cố gắng để khởi tạo các biến lưu trữ lười biếng với mã dưới đây.

class ViewController: UIViewController { 

    lazy var barButtonItem1 = UIBarButtonItem(barButtonSystemItem: .cancel, targetViewController: self, action: #selector(action)) 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     print(barButtonItem1.target) 
    } 
    func action() { } 
} 

Sau đó biên dịch lỗi nâng lên và nói

Không thể chuyển đổi giá trị của loại '(NSObject) ->() -> ViewController' để dự kiến ​​kiểu lập luận 'UIViewController?'

cho thấy trình biên dịch không xác định được rằng selfViewController. (Các initializer được cung cấp bởi UIKit sẽ biên dịch vì tham số thứ hai là của Any? mà chấp nhận giá trị của loại (NSObject) ->() -> ViewController.)

Nhưng khi cho loại chú thích vào biến lười biếng như

mã nguồn
lazy var barButtonItem1: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, targetViewController: self, action: #selector(action)) 

hạnh phúc biên soạn và barButtonItem1.target được đặt thành self.

Tôi tin rằng chú thích loại đã giúp biên dịch. Trên đây là lý do tôi đoán vấn đề bạn phải đối mặt là do lỗi trình biên dịch gây ra.


Xem thêm: có được báo cáo vấn đề tương tự như vấn đề bạn phải đối mặt. Cả hai đều được kết luận như một lỗi trình biên dịch.

Swift lazy instantiating using self

Type inference when using lazy instantiation

+0

Cảm ơn bạn! Vì vậy, nó thực sự là một lỗi trình biên dịch, hy vọng táo sẽ sửa chữa nó sớm. Bây giờ, hãy thêm chú thích kiểu. – user5685969