2014-06-14 14 views
44

Trong một ví dụ đơn giản như thế này, tôi có thể bỏ qua bản thân để tham chiếu backgroundLayer vì nó rõ ràng mà backgroundLayer backgroundColor được thiết lập.Khi nào tôi nên truy cập các thuộc tính với tính năng tự động nhanh chóng?

class SpecialView: UIView { 
    let backgroundLayer = CAShapeLayer() 

    init() { 
     backgroundLayer.backgroundColor = UIColor.greenColor().CGColor 
    } 
} 

Nhưng cũng giống như trong Mục tiêu-C, chúng ta có thể gây nhầm lẫn mọi thứ bằng cách thêm biến cục bộ (hoặc hằng số) có tên tương tự. Bây giờ backgroundColor đang được đặt trên lớp không hình dạng:

class SpecialView: UIView { 
    let backgroundLayer = CAShapeLayer() 

    init() { 
     var backgroundLayer = CALayer() 

     backgroundLayer.backgroundColor = UIColor.greenColor().CGColor 
    } 
} 

(điều này được giải quyết bằng cách sử dụng self.backgroundLayer.backgroundColor)

Trong Objective-C Tôi luôn tránh làm ivars đối với tài sản và tài sản luôn tiền tố tự cho rõ ràng. Tôi không phải lo lắng về ngà voi nhanh chóng nhưng có những cân nhắc khác khi tôi nên sử dụng bản thân một cách nhanh chóng?

+1

Cân nhắc chấp nhận giải pháp. –

Trả lời

68

Tôi không tin rằng có bất kỳ lý do gì mà bản thân sẽ được yêu cầu ngoài các biến cục bộ có cùng tên hoặc trong các bao đóng. Cá nhân, tôi thích để luôn luôn viết "bản ngã" vì:

  1. Đó là một dấu hiệu tức thời và rõ ràng rằng biến là một tài sản. Điều này là quan trọng bởi vì nó là một tài sản có nghĩa là trạng thái của nó có thể thay đổi rộng rãi hơn và theo những cách khác nhau hơn là một biến cục bộ. Ngoài ra, việc thay đổi thuộc tính có ý nghĩa lớn hơn việc thay đổi biến cục bộ.
  2. Mã này không cần phải được cập nhật nếu bạn quyết định để giới thiệu một tham số hoặc biến có cùng tên là tài sản
  3. Mã có thể dễ dàng sao chép vào và ra khỏi đóng cửa mà đòi hỏi tự
+1

Có và có. Đôi khi ngắn gọn và rõ ràng là tỷ lệ cược - luôn luôn sử dụng 'self' và bạn sẽ không bị choáng váng bởi một trường hợp hiếm hoi chồng lên nhau. –

+6

@NateCook Tôi thực sự đã gửi một lỗi với Apple về việc tự yêu cầu và tôi khuyến khích bạn làm tương tự nếu bạn đồng ý :) – drewag

+10

Lý do tôi thích * không * sử dụng bản thân là khi đóng cửa bắt buộc bạn sử dụng bản thân, sau đó nổi bật (đó là tốt, bởi vì tham chiếu tự trong một đóng cửa giữ lại nó, không giống như bối cảnh khác, vì vậy bạn muốn nó trông "khác nhau") –

17

Hầu hết thời gian chúng tôi có thể bỏ qua self. khi chúng tôi truy cập thuộc tính lớp học.

  1. Tuy nhiên có một thời gian khi chúng ta PHẢI sử dụng nó: khi chúng ta cố gắng thiết lập self.property trong một đóng cửa:

    dispatch_async(dispatch_get_main_queue(), { 
        // we cannot assign to properties of self 
        self.view = nil 
    
        // but can access properties 
        someFunc(view) 
    }) 
    
  2. một lần khi chúng tôi NÊN sử dụng nó: vì vậy bạn không làm hỏng biến cục bộ với thuộc tính lớp học:

    class MyClass { 
        var someVar: String = "class prop" 
    
        func setProperty(someVar:String = "method attribute") ->() { 
         print(self.someVar) // Output: class property 
         print(someVar) // Output: method attribute 
        } 
    } 
    
  3. other p ren, nơi chúng tôi CAN sử dụng self. trước khi thuộc tính chỉ để được thể hiện về là biến/hằng số xuất phát từ đó.

0

Như Nick đã nói, trong mục tiêu-c chúng tôi có các đặc tính tổng hợp để phân định mọi thứ. Ví dụ.

@IBOutlet (nonatomic,strong) UITableView *myTableView; 

dẫn đến _myTableView được (tốt nhất) tham chiếu trong nội bộ - và self.myTableView là tài liệu tham khảo bên ngoài lớp học. Trong khi điều này là khá màu đen và trắng, hãy xem xét các ngoại lệ khi lập trình instantiating lượt xem, bạn có thể đạt được rõ ràng/đơn giản/giảm boilerplate bằng cách loại bỏ tự.

@interface CustomVC:UIViewController 
{ 
    UITableView *myTableView; 
} 

Nhanh chóng, các thuộc tính công khai/nội bộ làm rõ phạm vi này. Nếu đó là tài sản công cộng, các lớp khác sẽ tương tác với lỗi trên bản thân. Nếu không, đó là tự bỏ qua nội bộ và tránh lặp lại tự động. Trình biên dịch sẽ bắt bạn khi cần thiết.

// UIViewcontroller swift header 
public var title: String? // Localized title for use by a parent controller. 
public var navigationItem: UINavigationItem { get } 

/// In your class 
self.title = "Clarity" 
self.navigationItem.leftBarButtonItem = UIBarButtonItem() 

// In superclass 
@property(nonatomic, copy) NSString *screenName // use self.screenName in swift subclass 

@IBOutlet myTableView:UITableView // use self 
public var myTableView:UITableView // use self 

internal var myTableView:UITableView // skip self 
var myTableView:UITableView // skip self 
1

Như tài liệu Apple nói trong https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Methods.html

Các tự tài sản

Mỗi thể hiện của một loại có một đặc tính tiềm ẩn được gọi là bản ngã, mà là chính xác tương đương với các trường hợp riêng của mình. Bạn sử dụng thuộc tính tự để tham chiếu đến cá thể hiện tại trong các phương thức của riêng nó.

Phương pháp thặng dư() trong ví dụ trên có thể được viết như thế này:

func increment() { 
    self.count += 1 
} 

Trong thực tế, bạn không cần phải viết tự trong mã của bạn rất thường xuyên. Nếu bạn không tự viết rõ ràng, Swift giả định rằng bạn đang giới thiệu cho thuộc tính hoặc phương pháp của phiên bản hiện tại bất cứ khi nào bạn sử dụng tên thuộc tính hoặc phương thức đã biết đã biết trong phương thức. Giả thiết này là được chứng minh bằng cách sử dụng số đếm (thay vì self.count) bên trong các phương thức ví dụ cho Bộ đếm.

Chính ngoại lệ cho quy tắc này xảy ra khi tên thông số cho phương thức thể hiện có cùng tên với thuộc tính của cá thể đó. Trong trường hợp này là , tên thông số được ưu tiên và trở thành cần thiết để tham chiếu đến thuộc tính theo cách có chất lượng hơn. Bạn sử dụng thuộc tính tự để phân biệt giữa tên thông số và tên thuộc tính .

Ở đây, tự disambiguates giữa một tham số phương pháp gọi là x và một tài sản dụ mà cũng được gọi là x:

struct Point { 
    var x = 0.0, y = 0.0 
    func isToTheRightOf(x: Double) -> Bool { 
     return self.x > x 
    } 
} 
let somePoint = Point(x: 4.0, y: 5.0) 
if somePoint.isToTheRightOf(x: 1.0) { 
    print("This point is to the right of the line where x == 1.0") 
} 
// Prints "This point is to the right of the line where x == 1.0" 

Nếu không có sự tự tiền tố, Swift sẽ giả định rằng cả hai công dụng của x gọi phương pháp này tham số được gọi là x.

Tôi muốn tiếp tục sử dụng bản thân mỗi khi tôi sử dụng thuộc tính để bỏ qua những hiểu lầm này.

0

Nhìn vào Ray Wenderlich's style guide

Sử dụng Tự

Đối conciseness, tránh sử dụng tự do Swift không yêu cầu nó để truy cập các thuộc tính của một đối tượng hoặc gọi phương thức của nó.

Chỉ sử dụng khi được trình biên dịch yêu cầu (trong @cách đóng khung hoặc trong bộ khởi tạo để phân biệt các thuộc tính khỏi đối số). Nói cách khác, nếu nó biên dịch mà không có bản thân thì hãy bỏ qua nó.

Apple's documentation đưa ra cùng một đề xuất.

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