31

Tôi đã chuyển dự án của mình sang ARC và tôi không hiểu liệu tôi có phải sử dụng strong hoặc weak cho IBOutlets hay không. Xcode làm điều này: trong xây dựng giao diện, nếu một tạo ra một UILabel ví dụ và tôi kết nối nó với trợ lý soạn thảo để ViewController của tôi, nó tạo này:yếu hoặc mạnh cho IBOutlet và

@property (nonatomic, strong) UILabel *aLabel; 

Nó sử dụng strong, thay vào đó tôi đọc một hướng dẫn trên trang web RayWenderlich nói điều này:

Nhưng đối với hai thuộc tính cụ thể này, tôi có các gói khác. Thay vì strong, chúng tôi sẽ khai báo chúng là weak.

@property (nonatomic, weak) IBOutlet UITableView *tableView; 
@property (nonatomic, weak) IBOutlet UISearchBar *searchBar; 

Weak là mối quan hệ khuyến khích cho tất cả ổ cắm tài sản. Các đối tượng chế độ xem này đã là một phần của chế độ xem của bộ điều khiển chế độ xem và không cần phải giữ lại ở nơi khác. Lợi thế lớn tuyên bố các cửa hàng của bạn weak là nó giúp bạn tiết kiệm thời gian bằng cách viết phương thức viewDidUnload .

Hiện nay chúng tôi viewDidUnload trông như thế này:

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    self.tableView = nil; 
    self.searchBar = nil; 
    soundEffect = nil; 
} 

Bây giờ bạn có thể đơn giản hóa nó như sau:

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    soundEffect = nil; 
} 

Vì vậy, sử dụng weak, thay vì strong, và loại bỏ các thiết lập để nil trong videDidUnload, thay vào đó Xcode sử dụng thứ e strong và sử dụng self... = nil trong số viewDidUnload.

Câu hỏi của tôi là: khi nào tôi phải sử dụng strong và khi weak? Tôi cũng muốn sử dụng cho mục tiêu triển khai iOS 4, vậy khi nào tôi phải sử dụng unsafe_unretain? Bất cứ ai cũng có thể giúp giải thích cho tôi tốt với một hướng dẫn nhỏ, khi sử dụng strong, weakunsafe_unretain với ARC?

Trả lời

69

Một nguyên tắc của ngón tay cái

Khi cha mẹ có một tham chiếu đến một đối tượng trẻ em, bạn nên sử dụng một tài liệu tham khảo strong. Khi một đứa trẻ có một tham chiếu đến đối tượng cha mẹ của nó, bạn nên sử dụng một tài liệu tham khảo weak hoặc unsafe_unretained một (nếu trước đây không có sẵn). Một kịch bản điển hình là khi bạn đối phó với các đại biểu. Ví dụ: UITableViewDelegate không giữ lại lớp bộ điều khiển có chứa chế độ xem bảng.

enter image description here

Dưới đây là một sơ đồ đơn giản để trình bày các khái niệm chính.

Giả sử đầu tiên A, B và C là tham chiếu strong. Đặc biệt, C có một số strong ref cho phụ huynh của nó. Khi obj1 được giải phóng (ở đâu đó), tham chiếu A không tồn tại nữa nhưng bạn bị rò rỉ vì có một chu kỳ giữa obj1 và obj2. Nói về số lượng giữ lại (chỉ cho mục đích giải thích), obj1 có số lượng giữ lại là 2 (obj2 có một tham chiếu strong), trong khi obj2 có số lượng giữ lại là 1. Nếu obj1 được giải phóng, số lượng giữ lại của nó là bây giờ 1 và phương thức dealloc của nó không được gọi. obj1 và obj2 vẫn còn trong bộ nhớ nhưng không ai có tham chiếu đến chúng: Leak.

Trên contary, nếu chỉ A và B là strong refs và C đủ điều kiện là weak tất cả đều ổn. Bạn không có rò rỉ. Trong thực tế, khi obj1 được giải phóng, nó cũng giải phóng obj2. Nói về số lượng giữ lại, obj1 có số lượng giữ lại là 1, obj2 có số lượng giữ lại 1. Nếu obj1 được giải phóng, số lần giữ lại của nó bây giờ là 0 và phương thức dealloc của nó được gọi. obj1 và obj2 bị xóa khỏi bộ nhớ.

Một đề xuất đơn giản: Bắt đầu suy nghĩ về đồ thị đối tượng khi bạn xử lý ARC.

Về câu hỏi đầu tiên của bạn, cả hai giải pháp đều hợp lệ khi bạn xử lý XIB. Nói chung, các tham chiếu weak được sử dụng khi bạn xử lý các chu kỳ bộ nhớ. Liên quan đến tệp XIBs, nếu bạn sử dụng strong, bạn cần đặt nil trong viewDidUnload vì nếu bạn không làm điều đó, trong điều kiện thiếu bộ nhớ, bạn có thể gây ra rò rỉ không mong muốn. Bạn không phát hành chúng trong dealloc vì ARC sẽ làm điều đó cho bạn. weak thay vì không cần xử lý đó kể từ khi đối tượng đích bị hủy, các giá trị đó được đặt là nil tự động. Không còn con trỏ lơ lửng nữa.

Nếu bạn quan tâm, tôi thực sự khuyên bạn nên đọc friday-qa-2012-04-13-nib-memory-management bởi Mike Ash.

Về câu hỏi thứ hai của bạn, nếu bạn cần hỗ trợ iOS 4, thay vì weak bạn phải sử dụng unsafe_unretained.

Trong vòng SO có rất nhiều câu hỏi/câu trả lời.Dưới đây là những người chính:

How do I replace weak references when using ARC and targeting iOS 4.0?

What kind of leaks does automatic reference counting in Objective-C not prevent or minimize?

using ARC, lifetime qualifier assign and unsafe_unretained

strong/weak/retain/unsafe_unretained/assign

Hy vọng rằng sẽ giúp.

Cập nhật

Theo nhận xét của shaunlim của, bắt đầu từ iOS 6 viewDidUnload phương pháp bị phản đối. Ở đây tôi thực sự khuyên bạn nên xem câu trả lời của Rob: iOS 6 - viewDidUnload migrate to didReceiveMemoryWarning?.

+0

cảm ơn câu trả lời – Piero

+0

bạn nói rằng, cho iboutlet nếu tôi sử dụng mạnh tôi phải sử dụng nil trong viewdidunload, và cho bộ nhớ thấp tôi không có rò rỉ, thay vào đó với yếu tôi không phải sử dụng nil trong videwdidunlaod, và cho bộ nhớ thấp cảnh báo tốt hơn là giải pháp mạnh hay yếu? – Piero

+0

Giống nhau. Sử dụng 'weak' cho phép bạn tiết kiệm thời gian viết mã (hai dòng trong trường hợp của bạn) bằng tay. Nhưng, Xcode làm điều đó cho bạn. Quan điểm cá nhân của tôi. Tôi thích sử dụng 'strong'. –

11

Bạn có thể sử dụng yếu cho các đối tượng được kết nối qua IBOutlets cho các đối tượng trong IB vì trong trường hợp này các đối tượng sẽ ở đó miễn là superview có. Điều này là do superview có một con trỏ mạnh mẽ đến các bản xem trước của nó.

Nếu con trỏ bạn đang xác định là con trỏ duy nhất cho đối tượng bạn nên khai báo là mạnh.

Nếu bạn là nhà phát triển đã đăng ký, tôi khuyên bạn nên xem xét các video từ WWDC11 và WWDC12.Một nguồn lực tốt là sự phát triển podcast iOS từ Stanford.

+0

Video WWDC12 có sẵn chưa? – borrrden

+0

Có, họ đang có! Thực sự nhanh chóng trong năm nay. – dasdom

+0

ok, nhưng tôi không hiểu, bìa câu hỏi của tôi cũng không an toàn_unretain, nhưng đối với IBOutlet tôi giải thích tốt, tại sao táo sử dụng mạnh? ... thay vì sử dụng yếu? ... vì vậy tôi phải làm theo táo? hoặc làm theo hướng dẫn raywenderlich nơi tôi viết trên một đoạn sử dụng yếu? – Piero

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