2011-10-07 23 views
35

Có một câu hỏi tương tự với điều này trên SO here, tuy nhiên tôi chỉ muốn làm rõ một điều gì đó chưa được giải thích đầy đủ ở đó.IBOutlet và xemDidUnload dưới ARC

Tôi hiểu rằng tất cả các đại biểu và cửa hàng - trên thực tế, có liên quan đến đối tượng "cha mẹ", là công dân tốt và suy nghĩ về đồ thị đối tượng trong một phút. Do tính chất của zeroing con trỏ yếu tự động giảm xuống còn 0 trên số lượng giữ lại của đối tượng được tham chiếu đạt đến 0, điều này có nghĩa là việc thiết lập IBOutlets thành nil trong viewDidUnload bây giờ là không cần thiết?

Vì vậy, nếu tôi tuyên bố ổ cắm của tôi như vậy:

@property (nonatomic, weak) IBOutlet UILabel *myLabel; 

Có đoạn mã sau có ảnh hưởng gì?

- (void)viewDidUnload 
{ 
    self.myLabel = nil; 

    [super viewDidUnload]; 
} 
+0

Tôi muốn biết lý do bỏ phiếu xuống? – Stuart

+0

Tôi cũng tò mò về câu trả lời nên tôi đã bỏ phiếu để chống lại. Tôi không biết câu trả lời ... – bryanmac

Trả lời

15

Chỉ cần làm một chút về nghiên cứu ...

Theo tôi được biết, yếu tương tự như chuyển nhượng, ở chỗ chúng tôi đều tham khảo yếu.

Tuy nhiên, việc gán không tạo tham chiếu zeroing. tức là nếu đối tượng được đề cập bị hủy và bạn truy cập vào thuộc tính đó, bạn S get nhận được BAD_ACCESS_EXCEPTION.

Thuộc tính yếu được tự động đánh số không (= nil) khi đối tượng được tham chiếu bị hủy.

Trong cả hai trường hợp, không cần thiết đặt thuộc tính thành 0, vì nó không đóng góp vào số lượng giữ lại của đối tượng được đề cập. Nó là cần thiết khi sử dụng thuộc tính giữ lại.

Rõ ràng, ARC cũng giới thiệu một thuộc tính "mạnh" mới, giống như "giữ lại"?

Nghiên cứu thực hiện here

+1

Cảm ơn bạn đã trả lời. Tôi hiểu các hoạt động của tham chiếu yếu, câu hỏi của tôi có liên quan nhiều hơn đến các cơ chế cơ bản 'viewDidUnload'. Nói cách khác, luôn luôn là trường hợp khung nhìn sẽ buộc tham chiếu yếu đến 'nil' trực tiếp sau lệnh gọi' viewDidUnload'? – Stuart

+2

Một lần nữa, ** như tôi đã hiểu nó **, Chế độ xem và các SubView của nó sẽ được phát hành khi nó bị xóa khỏi màn hình. Kể từ khi, yếu không tăng số lượng phát hành, và được số không khi tham chiếu của nó bị phá hủy, nó không cần thiết. –

+1

Xin lỗi, tôi đã bỏ lỡ phần câu trả lời của bạn khi tôi đọc nó lần đầu tiên. – Stuart

11

Tôi đã làm một thử nghiệm nhỏ và dường như mã kiểm tra vào viewDidUnload phương pháp không cần thiết. Để hỗ trợ điều này, các tài liệu cho viewDidUnload thực sự cho biết:

Khi phương pháp này được gọi, thuộc tính chế độ xem là không.

Cho biết rằng tham chiếu yếu phải được đặt thành nil tự động.

+3

Đây cũng là sự hiểu biết của tôi. Nhưng tại sao Xcode lại chèn câu lệnh '[self setMySubview: nil]' vào 'viewDidUnload' khi tạo các cửa hàng yếu? –

+2

Tôi nghĩ rằng nó _could_ là một tính năng còn sót lại từ mã pre-ARC, giống như khi bạn yêu cầu Xcode tạo lớp con 'NSManagedObject' cho Dữ liệu cốt lõi, các thuộc tính được tạo được đặt thành' giữ lại' thay vì 'mạnh '. Mặc dù trong trường hợp của các cửa hàng họ _are_ tạo ra là 'yếu'. Tôi đoán là nó không chủ ý. – Stuart

+0

Tôi đồng ý. UI giao diện người dùng có khả năng xảy ra lỗi khi thận trọng khi kéo và thả để tạo các cửa hàng trong mã. Các cài đặt nil đó có thể được xóa an toàn miễn là bạn đang sử dụng ARC và tham chiếu yếu trên các cửa hàng được đề cập. –

3

Từ sự hiểu biết của tôi về cách các cửa hàng được quản lý trong ARC nếu bạn đang sử dụng một tham chiếu yếu, bạn không cần phải thêm bất cứ điều gì để viewDidUnload vì nó đã là nil. Làm như vậy là do dự. Tuy nhiên, nếu bạn có cửa hàng mạnh, mà táo nói bạn nên làm gì nếu bạn đang trỏ đến một mục cấp cao nhất trong ngòi bút, thì bạn chắc chắn nên tiếp tục thêm dòng thích hợp trong viewDidUnload để không có những dòng này.

+0

Tôi muốn biết, nếu tôi định nghĩa '@property (nonatomic, strong) IBOutlet UILabel * myLabel;', tôi có cần định nghĩa 'self.myLabel = nil;' trong hàm 'viewDidUnload' hay không. – BlackMamba

5

Tôi có một số bằng chứng thực nghiệm để hỗ trợ rằng IBOutlets thực sự đã được đặt thành không tự động. Dưới đây là những gì tôi đã làm:

  1. tôi thiết lập ivars rõ ràng đối với tài sản IBOutlet tôi (@synthesize myLabel = myLabel_) vì vậy mà tôi sau đó có thể kiểm tra giá trị của họ trong chương trình gỡ rối.
  2. Tôi đã bật điểm ngắt trên dòng đầu tiên của viewDidUnload.
  3. Tôi đã sắp xếp cho viewDidUnload để được gọi bằng cách mô phỏng cảnh báo bộ nhớ.
  4. Tôi đã kiểm tra các giá trị của các ivars rõ ràng mà tôi liên kết với các thuộc tính IBOutlet của mình.

Tất cả ivars rõ ràng đều có giá trị là nil sau đó tôi nhấn điểm ngắt.

0

Bắt đầu từ iOS 5 và OS X 10.7, weak sẽ tạo ra con trỏ dừng tự động. Điều này có nghĩa là khi đối tượng nhọn được nhả ra, con trỏ được tự động đặt thành nil (để biết chi tiết, xem Zeroing Weak References in ARC).

Vì vậy, dưới iOS 5+ và OS X 10.7+, nó không phải là hữu ích để thiết lập weakIBOutlet tính để nil bằng tay trong các phương pháp viewDidUnload: khi giao diện chính không có đạn thì tất cả subviews của nó sẽ được phát hành, do đó các thuộc tính liên quan được đặt thành nil.

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