Giải thích về bộ nhớ mạnh và yếu trong iOS5


114

Tôi chưa quen với việc phát triển iOS5 và sử dụng mục tiêu-c. Tôi khó hiểu sự khác biệt giữa bộ nhớ mạnhyếu . Tôi đã đọc tài liệu và các câu hỏi SO khác, nhưng tất cả chúng đều giống hệt tôi mà không có cái nhìn sâu sắc hơn.

Tôi đã đọc tài liệu: Chuyển đổi sang ARC - tài liệu này tham chiếu đến các điều khoản giữ lại, chuyển nhượng và phát hành iOS4; khiến tôi bối rối. Sau đó, tôi xem xét Open U CS193p, nơi nó phân biệt mạnh và yếu:

Mạnh : "giữ cái này trong đống cho đến khi tôi không chỉ vào nó nữa"
Yếu : "giữ cái này miễn là người khác chỉ vào nó mạnh"

Không phải hai định nghĩa giống hệt nhau = nếu con trỏ không còn trỏ đến một đối tượng, sau đó giải phóng bộ nhớ giữ đối tượng? Tôi hiểu khái niệm về con trỏ, đống, phân bổ hoặc phân bổ bộ nhớ - nhưng sự khác biệt giữa mạnh và yếu là gì?


Mô hình quản lý bộ nhớ vẫn có liên quan ngay cả khi bạn đang sử dụng ARC. Bạn vẫn phải hiểu cách đếm tham chiếu, bạn không cần phải làm điều đó theo cách thủ công. Vì vậy, đoạn cuối của bạn là một yêu cầu không hợp lý.
jrturton

Câu trả lời:


509

Sự khác biệt là một đối tượng sẽ được phân bổ ngay khi không có con trỏ mạnh nào đến nó. Ngay cả khi con trỏ yếu trỏ tới nó, một khi con trỏ mạnh cuối cùng biến mất, đối tượng sẽ được phân bổ và tất cả các con trỏ yếu còn lại sẽ bị xóa.

Có lẽ một ví dụ là theo thứ tự.

Hãy tưởng tượng đối tượng của chúng ta là một con chó, và con chó đó muốn chạy trốn (được định vị).

Những kẻ chỉ điểm mạnh mẽ giống như một sợi dây buộc trên con chó. Chỉ cần bạn buộc dây xích vào người, chó sẽ không bỏ chạy. Nếu năm người gắn dây xích của họ vào một con chó, (năm con trỏ mạnh vào một đối tượng), thì con chó sẽ không bỏ chạy cho đến khi tất cả năm dây xích được tháo ra.

Mặt khác, những người chỉ điểm yếu giống như những đứa trẻ chỉ vào con chó và nói "Nhìn kìa! Một con chó!" Miễn là con chó vẫn còn trên dây xích, những đứa trẻ nhỏ vẫn có thể nhìn thấy con chó và chúng sẽ vẫn chỉ vào nó. Tuy nhiên, ngay sau khi tất cả các dây xích được tháo ra, con chó chạy đi cho dù có bao nhiêu đứa trẻ đang chỉ vào nó.

Ngay sau khi con trỏ mạnh cuối cùng (dây xích) không còn trỏ đến một đối tượng, đối tượng sẽ được phân bổ và tất cả các con trỏ yếu sẽ bị xóa.


2
Nó dựa trên một sự tương tự Malcom Crawford tại Apple đã đưa ra cách đây vài năm. Không biết anh ta lấy nó ở đâu.
BJ Homer

Tôi nhớ mình đã đọc một thứ tương tự (tiền truyện) trong một cuốn sách, nghĩ rằng đó là Hillegass, nhưng rồi anh ấy có thể lấy nó từ một nơi khác ... đó là một cuốn sách hay!
jrturton

14
+1 ví dụ xuất sắc. nó là một dẫn xuất của ví dụ của Hillegass về cách dây xích được giữ lại / phát hành, nhưng tôi thích sự thích nghi này cho mạnh / yếu.
Dave DeLong

2
@DaveDeLong: Chà, chúng bất hợp pháp vào ngày 10.6 với ARC. Bạn hoàn toàn không thể sử dụng chúng. Vì vậy, đó là một điểm không liên quan.
BJ Homer

5
Một cái hay khác là bóng bay Heli: miễn là giữ ít nhất một sợi dây, nó sẽ không trôi đi. Các phép tương tự xích / bong bóng cũng rất tốt trong việc khiến mọi người quên rằng "quyền sở hữu" được quản lý bằng cách giữ lại / phát hành.
Steve Weller

34

Không phải là hai định nghĩa giống hệt nhau.

Tuyệt đối không. Sự khác biệt chính trong hai định nghĩa mà bạn đã chỉ ra là "miễn là người khác". Đó là "người khác" là quan trọng.

Hãy xem xét những điều sau:

__strong id strongObject = <some_object>;
__weak id weakObject = strongObject;

Bây giờ chúng ta có hai gợi ý <some_object>, một điểm mạnh và một điểm yếu. Nếu chúng ta thiết lập strongObjectđể nilthích như vậy:

strongObject = nil;

Sau đó, nếu bạn thực hiện các quy tắc bạn đã vạch ra thì bạn sẽ tự hỏi mình những câu hỏi sau:

  1. Mạnh mẽ: "giữ cái này trong đống cho đến khi tôi không chỉ vào nó nữa"

    strongObjectkhông chỉ ra <some_object>bất kỳ nữa. Vì vậy, chúng ta không cần phải giữ nó.

  2. Yếu: "giữ điều này miễn là người khác chỉ mạnh vào nó"

    weakObjectvẫn chỉ đến <some_object>. Nhưng vì không ai khác chỉ ra nó, nên quy tắc này cũng có nghĩa là chúng ta không cần phải giữ nó.

Kết quả là nó <some_object>được phân bổ và nếu thời gian chạy của bạn hỗ trợ nó (Lion và iOS 5 trở lên) thì weakObjectsẽ tự động được đặt thành nil.

Bây giờ xem xét những gì sẽ xảy ra nếu chúng ta thiết lập weakObjectđể nilthích như vậy:

weakObject = nil;

Sau đó, nếu bạn thực hiện các quy tắc bạn đã vạch ra thì bạn sẽ tự hỏi mình những câu hỏi sau:

  1. Mạnh mẽ: "giữ cái này trong đống cho đến khi tôi không chỉ vào nó nữa"

    strongObjectkhông trỏ đến <some_object>. Vì vậy, chúng ta cần phải giữ nó.

  2. Yếu: "giữ điều này miễn là người khác chỉ mạnh vào nó"

    weakObjectkhông trỏ đến <some_object>.

Kết quả là <some_object>được không deallocated, nhưng weakObjectsẽ là nilcon trỏ.

[Lưu ý rằng tất cả những gì đang giả định <some_object>không được trỏ tới bởi một tham chiếu mạnh khác ở một nơi khác / một số phương tiện khác để được "nắm giữ"]


1
Vì vậy, sự khác biệt chính giữa điểm mạnh và điểm yếu là sự định vị của các đối tượng được trỏ vào một cách mạnh mẽ sẽ tự động loại bỏ tất cả các con trỏ yếu có liên quan. Và đối với một con trỏ yếu để chỉ vào điều gì đó, luôn tồn tại một con trỏ mạnh. Nếu vậy, đối tượng ứng dụng chính phải được trỏ mạnh đến?
KMC

Đối với một con trỏ yếu để trỏ đến một cái gì đó hợp lệ thì phải có một con trỏ mạnh. Thêm vào đó là thực tế là iOS 5 và Lion hỗ trợ tự động loại bỏ các tham chiếu yếu và bạn sẽ hiểu được những gì mình nói. Mặc dù vậy , thời gian chạy của iOS 4 không hỗ trợ điều đó. "Đối tượng ứng dụng chính" Tôi cho rằng bạn có nghĩa là UIApplicationđối tượng? Điều đó sẽ được tham chiếu mạnh mẽ bởi hoạt động bên trong của UIKit- nhưng bạn không cần phải lo lắng về điều đó.
mattjgalloway

Tôi nghĩ rằng bạn có thể sử dụng từ như "strongObjectPointer" thay vì "strongObject". Vì vậy Người mới học lập trình sẽ có ý nghĩa tốt hơn. Rất tốt trên @BJ Homer bài đăng Mr.Matt.Interesting :)
Vijay-Apple-Dev.blogspot.com

2

Mạnh

  1. Tạo quyền sở hữu giữa tài sản và giá trị được chỉ định.
  2. Đây là mặc định cho thuộc tính đối tượng trong ARC vì vậy nó không khiến bạn lo lắng về số lượng tham chiếu và tự động giải phóng tham chiếu.
  3. Nó là thay thế cho giữ lại. Chúng tôi sử dụng nếu và chỉ khi chúng tôi cần sử dụng như giữ lại.

Yếu

  1. Tạo ra quyền không sở hữu giữa tài sản và giá trị được chỉ định.
  2. Strong được sử dụng trên đối tượng cha và yếu được sử dụng trên đối tượng con khi cha mẹ được phát hành thì tham chiếu đối tượng con cũng được đặt thành nil
  3. Nó giúp ngăn chặn các chu kỳ lưu giữ.
  4. Nó không bảo vệ đối tượng được tham chiếu khi thu thập bởi bộ thu gom rác.
  5. Yếu là bản chất được giao, tài sản không chắc chắn.

Điều đáng nói ở đây là chu kỳ giữ lại thường là gì. Chúng ta có hai đối tượng: đối tượng A và đối tượng B. Đối tượng A có tham chiếu mạnh đến đối tượng B và đối tượng B có tham chiếu mạnh đến đối tượng A. Không có gì khác có tham chiếu mạnh đến đối tượng A hoặc B.
boro

2

Một ví dụ khác: Sinh viên được Objectcho rằng cô ấy / anh ấy có thể tốt nghiệp ( deallocate) miễn là cô ấy / anh ấy hoàn thành tất cả các khóa học chính ( strong pointers), cho dù cô ấy / anh ấy có tham gia các khóa học tùy chọn ( weak pointers) hay không. Nói cách khác: con trỏ mạnh là yếu tố duy nhất giải quyết vấn đề đó Object.


1

Không, chúng không giống nhau nhưng rất khác nhau. Bạn chỉ sử dụng strong nếu bạn cần giữ lại đối tượng. Bạn sử dụng yếu trong bất kỳ trường hợp nào khác, với lợi thế là bạn có thể biết liệu đối tượng ha có bị xóa khỏi đống hay không vì không ai giữ lại nó.


1

Tôi biết mình đến với bữa tiệc này khá muộn, nhưng tôi nghĩ điều quan trọng là phải nhầm lẫn vấn đề bằng cách chỉ ra rằng ý nghĩa của "mô hình bộ nhớ mạnh và yếu" phụ thuộc vào việc bạn đang nói về phần mềm hay phần cứng.

Đối với phần cứng, yếu hay mạnh cho biết liệu có hỗ trợ tính nhất quán tuần tự hay không.

[SC có nghĩa là] ... kết quả của bất kỳ quá trình thực thi nào cũng giống như nếu các hoạt động của tất cả các bộ xử lý được thực hiện theo một số thứ tự tuần tự và các hoạt động của mỗi bộ xử lý riêng lẻ xuất hiện theo trình tự này theo thứ tự được chỉ định bởi chương trình của nó. - Lamport, 1979

WTF có liên quan gì đến bộ nhớ không? Nó ngụ ý rằng việc ghi vào các biến bởi các bộ xử lý khác nhau phải được tất cả các bộ xử lý nhìn thấy theo cùng một thứ tự. Trong phần cứng với một mô hình mạnh mẽ, điều này được đảm bảo. Trên phần cứng có kiểu máy yếu thì không.

Các câu trả lời hiện tại chỉ giải thích câu hỏi theo mô hình bộ nhớ phần mềm. Phần cứng không phải là không liên quan đến lập trình. Câu hỏi này đề cập đến iOS, thường chạy trên bộ xử lý Arm7. Arm7 có một mô hình bộ nhớ yếu. Đối với các lập trình viên đã quen với bộ vi xử lý có mô hình mạnh - đó là tất cả chúng ta vì x86 và x64 có mô hình mạnh - đây là một cái bẫy khủng khiếp. Sử dụng bool để báo hiệu một luồng khác thoát ra hoạt động tốt trong một mô hình mạnh. Mã tương tự trên Arm hoàn toàn không hoạt động trừ khi bạn đánh dấu cờ dễ bay hơi, và thậm chí sau đó nó thất thường.

Mặc dù đúng là Arm8 + thay đổi hoàn toàn điều này với hỗ trợ rõ ràng cho việc mua / phát hành, phần mềm cũ không sử dụng hỗ trợ này. Phần mềm kế thừa bao gồm tất cả ba hệ điều hành điện thoại và mọi thứ chạy trên chúng, cũng như trình biên dịch và thư viện cho đến khi chúng được cập nhật.

Để có một cuộc kiểm tra mở rộng về chủ đề này, tôi giới thiệu bạn đến Máy cắt cỏ không thể bắt chước .

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.