Sự khác biệt giữa mạnh và yếu trong Objective-C


308

Tôi mới biết về Obj-C, vì vậy câu hỏi đầu tiên của tôi là:

Sự khác biệt giữa strongweaktrong @propertykhai báo con trỏ đến các đối tượng là gì?

Ngoài ra, nonatomiccó nghĩa là gì?


19
thực ra đây là một câu hỏi hay, đôi khi, chúng tôi quên mất khái niệm cơ bản về sở thích mạnh / yếu và nguyên tử / không nguyên tử .... :) Cảm ơn bạn đã nhắc nhở chúng tôi về nó ...
andikurnia

10
@JackyBoy Điều thú vị là tìm kiếm đơn giản được đề xuất trên google dẫn tôi đến đây lol. #circularreference
Jason Renaldo

10
Tôi có xu hướng không tin tưởng nhiều câu trả lời trên google nhưng luôn tham khảo SO để có câu trả lời thông minh
JeffK

Câu trả lời:


642

Một tham chiếu mạnh (mà bạn sẽ sử dụng trong hầu hết các trường hợp) có nghĩa là bạn muốn "sở hữu" đối tượng bạn đang tham chiếu với thuộc tính / biến này. Trình biên dịch sẽ quan tâm rằng bất kỳ đối tượng nào bạn gán cho thuộc tính này sẽ không bị hủy miễn là bạn trỏ đến nó với một tham chiếu mạnh. Chỉ khi bạn đặt thuộc tính thành nilđối tượng sẽ bị phá hủy (trừ khi một hoặc nhiều đối tượng khác cũng có tham chiếu mạnh đến nó).

Ngược lại, với một tham chiếu yếu, bạn biểu thị rằng bạn không muốn kiểm soát thời gian tồn tại của đối tượng. Đối tượng bạn đang tham chiếu yếu chỉ sống vì ít nhất một đối tượng khác có tham chiếu mạnh đến nó. Khi đó không còn là trường hợp nữa, đối tượng sẽ bị hủy và thuộc tính yếu của bạn sẽ tự động được đặt thành nil. Các trường hợp sử dụng thường xuyên nhất của các tài liệu tham khảo yếu trong iOS là:

  1. thuộc tính ủy nhiệm, thường được tham chiếu yếu để tránh chu kỳ giữ lại và

  2. các khung nhìn / điều khiển của khung nhìn chính của trình điều khiển khung nhìn vì các khung nhìn đó đã được giữ vững bởi khung nhìn chính.

nguyên tử so với nonatomic đề cập đến sự an toàn của luồng của các phương thức getter và setter mà trình biên dịch tổng hợp cho thuộc tính. nguyên tử (mặc định) báo cho trình biên dịch làm cho các phương thức truy cập an toàn theo luồng (bằng cách thêm khóa trước khi truy cập ivar) và nonatomic thì ngược lại. Ưu điểm của nonatomic là hiệu suất cao hơn một chút. Trên iOS, Apple sử dụng nonatomic cho hầu hết tất cả các thuộc tính của họ, vì vậy lời khuyên chung là bạn nên làm như vậy.


28
@Bourne: Điều đó phụ thuộc vào ý của bạn về độ an toàn của luồng. atomicđảm bảo rằng tài sản có thể được đọc và viết một cách an toàn từ nhiều chủ đề cùng một lúc. Điều đó không có nghĩa là một đối tượng có tất cả các thuộc tính được atomictự động an toàn luồng.
Ole Begemann

3
Chi tiết tuyệt vời. Tôi nghĩ rằng tôi đã không thực sự có được nó cho đến bây giờ. Cảm ơn bạn.
ahmedalkaff

1
Theo tài liệu của apple, nguyên tử và không gây dị ứng phải đồng nghĩa với an toàn luồng. developer.apple.com/l
Library / ios / document / cocoa / conceptionual / từ

5
"Lưu ý: Tính nguyên tử của tài sản không đồng nghĩa với an toàn luồng của đối tượng." developer.apple.com/l
GS

Tại sao chúng ta không xóa ví dụ khi chúng ta không muốn? Tại sao chúng ta không thể lấy không khí ra khỏi khinh khí cầu hoặc phá hủy nó khi chúng ta không muốn, tại sao chúng ta phải quan tâm đến các chuỗi đính kèm? Chúng tôi chỉ cần dữ liệu.
Ashish Pisey

707

Có thể hữu ích khi nghĩ về các tài liệu tham khảo mạnh và yếu về mặt bóng bay.

Một quả bóng sẽ không bay đi miễn là có ít nhất một người đang giữ một sợi dây gắn vào nó. Số người giữ chuỗi là số giữ lại. Khi không có ai cầm dây, ballon sẽ bay đi (dealloc). Nhiều người có thể có dây để cùng một quả bóng. Bạn có thể nhận / đặt thuộc tính và phương thức gọi trên đối tượng được tham chiếu với cả tham chiếu mạnh và yếu.

Một tài liệu tham khảo mạnh mẽ giống như giữ một chuỗi cho quả bóng đó. Miễn là bạn đang giữ một sợi dây gắn vào quả bóng bay, nó sẽ không bay đi.

Một tài liệu tham khảo yếu giống như nhìn vào quả bóng. Bạn có thể thấy nó, truy cập các thuộc tính của nó, gọi đó là các phương thức, nhưng bạn không có chuỗi nào cho quả bóng đó. Nếu mọi người đang giữ dây cho phép, quả bóng bay đi và bạn không thể truy cập nó nữa.


68
+2 (nếu tôi có thể). Nghiêm túc, giải thích thực sự sáng tạo!
Con Antonakos

25
Sau nhiều năm 1 và một nửa của iOS đang phát triển, tôi nghĩ rằng chỉ bây giờ tôi hiểu rõ những gì strongweakthực sự có ý nghĩa.
Isuru

17
@ X.Li Chu kỳ giữ lại giống như bạn có 2 dây cho ballon, một trong số chúng thuộc sở hữu của bạn (vì vậy bạn sở hữu ballon này), dây còn lại thuộc sở hữu của ballon (vì vậy ballon này sở hữu bạn). Vì bạn chỉ có quyền truy cập vào chuỗi của mình, làm thế nào để bạn để ballon đi nếu ballon không muốn đi? Vì vậy, tốt hơn là bạn sở hữu ballon (mạnh) trong khi ballon không sở hữu bạn (yếu). Khi bạn muốn để nó đi, chỉ cần cắt chuỗi :)
snakeninny

5
Đọc hồ sơ của anh ấy, anh ấy là một người hướng dẫn iOS. Giải thích rất sáng tạo !!
Ngã

3
Nguyên tử so với phi nguyên tử Tôi nghĩ có thể được mô tả như một phòng vệ sinh công cộng có nhiều cửa, với một nhà vệ sinh ở trung tâm. Khi ai đó vào nhà vệ sinh qua một cánh cửa, anh ta cũng có thể khóa tất cả các cửa khác vào nhà vệ sinh nếu anh ta không muốn trải nghiệm khoảnh khắc khó xử. Cười lớn. Cảm ơn bạn đã đọc tương tự vô nghĩa này.
Chen Li Yong

24

strong : gán giá trị đến cho nó, nó sẽ giữ lại giá trị đến và giải phóng giá trị hiện có của biến thể hiện

Yếu : sẽ gán giá trị đến cho nó mà không giữ lại.

Vì vậy, sự khác biệt cơ bản là giữ lại biến mới. Bạn muốn giữ lại nó nhưng có những tình huống bạn không muốn có nó nếu không bạn sẽ có một chu kỳ giữ lại và không thể giải phóng bộ nhớ cho các đối tượng. Ví dụ. obj1 giữ lại obj2 và obj2 giữ lại obj1. Để giải quyết loại tình huống này, bạn sử dụng tài liệu tham khảo yếu.


12

Một câu trả lời giả: -

Tôi nghĩ rằng lời giải thích được đưa ra trong câu trả lời ở trên, vì vậy tôi sẽ chỉ cho bạn biết nơi sử dụng STRONGvà nơi sử dụng WEAK:

Sử dụng Weak: - 1. Đại biểu 2. Cửa hàng 3. Tổng quan 4. Điều khiển, v.v.

Sử dụng Strong: - Còn lại ở mọi nơi không bao gồm trong WEAK.


2
Và những gì không chứa: P
Rajneesh071

3
webView, mapView, v.v.
shubham mishra 6/10/2016

4
thực ra hầu hết các cuộc phỏng vấn mà chúng ta kéo và thả trên bảng phân cảnh
shubham mishra

8

mạnhyếu , những từ khóa này xoay quanh quyền sở hữu đối tượng trong Objective-C

Quyền sở hữu đối tượng là gì?

Các biến con trỏ ngụ ý quyền sở hữu của các đối tượng mà chúng trỏ đến.

  • Khi một phương thức (hoặc hàm) có một biến cục bộ trỏ đến một đối tượng, biến đó được cho là sở hữu đối tượng được trỏ tới.
  • Khi một đối tượng có một biến đối tượng trỏ đến một đối tượng khác, đối tượng có con trỏ được cho là sở hữu đối tượng được trỏ tới.

Bất cứ khi nào một biến con trỏ trỏ đến một đối tượng, đối tượng đó có chủ sở hữu và sẽ tồn tại. Điều này được biết đến như là một mạnh mẽ tài liệu tham khảo .

Một biến có thể tùy ý không có quyền sở hữu đối tượng mà nó trỏ đến. Một biến không có quyền sở hữu đối tượng được gọi là yếu tham chiếu .

Hãy xem giải thích chi tiết tại đây Làm sáng tỏ @property và các thuộc tính



6

mạnh là mặc định. Một đối tượng vẫn còn sống còn sống miễn là có một con trỏ mạnh đến nó.

yếu chỉ định một tham chiếu không giữ cho đối tượng được tham chiếu tồn tại. Một tham chiếu yếu được đặt thành không khi không có tham chiếu mạnh đến đối tượng.


2

Để hiểu tham chiếu Mạnh và Yếu, hãy xem xét ví dụ dưới đây, giả sử chúng ta có phương thức có tên là displayLocalVariable.

 -(void)displayLocalVariable
  {
     UIView* myView = [[UIView alloc] init];
     NSLog(@"myView tag is = %ld", myView.tag);
  }

Trong phạm vi phương thức trên, biến myView bị giới hạn ở phương thức displayLocalVariable, một khi phương thức kết thúc biến myView đang giữ đối tượng UIView sẽ bị giải phóng khỏi bộ nhớ.

Bây giờ nếu chúng ta muốn giữ biến myView trong suốt vòng đời của bộ điều khiển xem. Để làm điều này, chúng ta có thể tạo thuộc tính có tên là usernameView sẽ có tham chiếu mạnh đến biến myView (xem @property(nonatomic,strong) UIView* usernameView;self.usernameView = myView;trong mã bên dưới), như dưới đây,

@interface LoginViewController ()

@property(nonatomic,strong) UIView* usernameView;
@property(nonatomic,weak) UIView* dummyNameView;

- (void)displayLocalVariable;

@end

@implementation LoginViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

}

-(void)viewWillAppear:(BOOL)animated
{
     [self displayLocalVariable];
}

- (void)displayLocalVariable
{
   UIView* myView = [[UIView alloc] init];
   NSLog(@"myView tag is = %ld", myView.tag);
   self.usernameView = myView;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}


@end

Bây giờ trong đoạn mã trên, bạn có thể thấy myView đã được gán cho self.usernameView và self.usernameView đang có một tham chiếu mạnh mẽ (như chúng tôi đã khai báo trong giao diện sử dụng @property) cho myView. Do đó myView sẽ không bị xử lý từ bộ nhớ cho đến khi self.usernameView còn sống.

  • Tham khảo yếu

Bây giờ hãy xem xét việc gán myName cho dummyNameView là một tham chiếu yếu, self.dummyNameView = myView;không giống như tham chiếu mạnh, yếu sẽ chỉ giữ myView cho đến khi có tham chiếu mạnh đến myView. Xem mã dưới đây để hiểu tài liệu tham khảo yếu,

-(void)displayLocalVariable
  {
     UIView* myView = [[UIView alloc] init];
     NSLog(@"myView tag is = %ld", myView.tag);
     self.dummyNameView = myView;
  }

Trong đoạn mã trên có tham chiếu yếu đến myView (tức là self.dummyNameView đang có tham chiếu yếu đến myView) nhưng không có tham chiếu mạnh đến myView, do đó self.dummyNameView sẽ không thể giữ giá trị myView.

Bây giờ một lần nữa xem xét các mã dưới đây,

-(void)displayLocalVariable
      {
         UIView* myView = [[UIView alloc] init];
         NSLog(@"myView tag is = %ld", myView.tag);
         self.usernameView = myView;
         self.dummyNameView = myView;
      } 

Trong mã trên, self.usernameView có tham chiếu mạnh đến myView, do đó self.dummyNameView sẽ có giá trị myView ngay cả sau khi phương thức kết thúc do myView có tham chiếu mạnh được liên kết với nó.

Bây giờ, bất cứ khi nào chúng ta tạo một tham chiếu mạnh đến một biến, số lượng giữ lại của nó sẽ tăng thêm một và biến đó sẽ không bị hủy cho đến khi số giữ của nó đạt đến 0.

Hi vọng điêu nay co ich.


2019-07-25 12: 33: 15.479002 + 0530 StrongAndWeak [6329: 245483] Tên tôi là = ABC 2019-07-25 12: 33: 15.479226 + 0530 StrongAndWeak [6329: 245483] Tên tôi là mạnh = ABC 2019 07-25 12: 33: 15.479418 + 0530 StrongAndWeak [6329: 245483] Tên tôi là dành cho yếu = ABC trong trường hợp này, bạn đã nói với tài sản yếu không có giá trị của tên tôi. ..? bạn có thể đưa ra câu trả lời rõ ràng hơn không .... Cảm ơn trước
Madhu_Nani

@Raviteja_DevObal ARC không hứa sẽ làm điều đó ngay lập tức (tức là giải quyết chuỗi @ "ABC"), nhưng nó sẽ được giải quyết chắc chắn sau này ...
Mahadev Mandale

@Raviteja_DevObal Như giải thích ở đây chuỗi là một ví dụ tồi cho việc này. Tôi đã cập nhật câu trả lời của mình với đối tượng UIView, hy vọng nó có ích.
Mahadev Mandale

1

Mạnh : Về cơ bản được sử dụng với các thuộc tính mà chúng ta đã sử dụng để nhận hoặc gửi dữ liệu từ / vào các lớp khác. Yếu : Thông thường tất cả các cửa hàng, kết nối thuộc loại Yếu từ Giao diện.

Nonatomic : Loại thuộc tính như vậy được sử dụng trong các điều kiện khi chúng tôi không muốn chia sẻ ổ cắm hoặc đối tượng của mình thành các Chủ đề đồng thời khác nhau. Nói cách khác, thể hiện Nonatomic làm cho các thuộc tính của chúng ta xử lý một luồng tại một thời điểm. Hy vọng nó hữu ích cho bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.