Tôi muốn biết bạn đã sử dụng trong tình huống nào -retainCount
cho đến nay và cuối cùng là những vấn đề có thể xảy ra khi sử dụng nó.
Cảm ơn.
Tôi muốn biết bạn đã sử dụng trong tình huống nào -retainCount
cho đến nay và cuối cùng là những vấn đề có thể xảy ra khi sử dụng nó.
Cảm ơn.
Câu trả lời:
Bạn không bao giờ nên sử dụng -retainCount
, bởi vì nó không bao giờ cho bạn biết bất cứ điều gì hữu ích. Việc triển khai các khuôn khổ Foundation và AppKit / UIKit là không rõ ràng; bạn không biết những gì đang được giữ lại, tại sao nó được giữ lại, ai đang giữ lại nó, khi nào nó được giữ lại, v.v.
Ví dụ:
[NSNumber numberWithInt:1]
sẽ có một retainCount
trong số 1. Nó không. Đó là 2.@"Foo"
sẽ có một retainCount
trong số 1. Nó không. Đó là 1152921504606846975.[NSString stringWithString:@"Foo"]
sẽ có một retainCount
trong số 1. Nó không. Một lần nữa, đó là 1152921504606846975.Về cơ bản, vì bất cứ thứ gì cũng có thể giữ lại một đối tượng (và do đó thay đổi nó retainCount
), và vì bạn không có nguồn của hầu hết mã chạy một ứng dụng, nên một đối tượng retainCount
là vô nghĩa.
Nếu bạn đang cố gắng tìm ra lý do tại sao một đối tượng không được phân bổ, hãy sử dụng công cụ Leaks trong Instruments. Nếu bạn đang cố gắng tìm ra lý do tại sao một đối tượng lại được định vị quá sớm, hãy sử dụng công cụ Zombies trong Instruments.
Nhưng không sử dụng -retainCount
. Đó là một phương pháp thực sự vô giá trị.
biên tập
Xin mọi người vào http://bugreport.apple.com và yêu cầu-retainCount
không dùng nữa. Càng nhiều người yêu cầu nó càng tốt.
chỉnh sửa # 2
Là một bản cập nhật, [NSNumber numberWithInt:1]
hiện có retainCount
mã là 9223372036854775807. Nếu mã của bạn mong đợi nó là 2, thì mã của bạn hiện đã bị hỏng.
- (NSUInteger)retainCount{return NSUIntegerMax;}
.
retainCount
.
Nghiêm túc. Đừng làm vậy.
Chỉ cần làm theo hướng dẫn quản lý bộ nhớ và chỉ phát hành những gì bạn alloc
, new
hoặc copy
(hoặc bất cứ điều gì bạn gọi retain
khi ban đầu).
@bbum đã nói điều đó tốt nhất ở đây trên SO , và thậm chí còn chi tiết hơn trên blog của anh ấy .
-retainCount
được (với nhiều chi tiết hơn) từ Instruments và các công cụ của nó.
retain
, retain
, retain
, autorelease,
autorelease, autorelease
có thể là một kết quả hoàn toàn hợp lệ của thông qua một đối tượng thông qua API UIKit, ví dụ.
Các đối tượng được phát hành tự động là một trường hợp mà việc kiểm tra -retainCount là không thông tin và có khả năng gây hiểu lầm. Số lượng lưu giữ không cho bạn biết về số lần -autorelease đã được gọi trên một đối tượng và do đó, nó sẽ được giải phóng bao nhiêu lần khi nhóm autorelease hiện tại cạn kiệt.
Tôi làm tìm retainCounts rất hữu ích khi kiểm tra sử dụng 'cụ'.
Sử dụng công cụ 'phân bổ', hãy đảm bảo rằng 'Số lượng tham chiếu bản ghi' được bật và bạn có thể truy cập vào bất kỳ đối tượng nào và xem lịch sử KeepCount của nó.
Bằng cách ghép nối các phân bổ và phát hành, bạn có thể có được bức tranh tốt về những gì đang diễn ra và thường giải quyết những trường hợp khó khăn khi một thứ gì đó không được phát hành.
Điều này chưa bao giờ khiến tôi thất vọng - bao gồm cả việc tìm ra lỗi trong các bản phát hành beta sớm của iOS.
Hãy xem tài liệu của Apple về NSObject, nó bao gồm khá nhiều câu hỏi của bạn: NSObject keepCount
Tóm lại, keepCount có thể vô dụng với bạn trừ khi bạn đã triển khai hệ thống đếm tham chiếu của riêng mình (và tôi gần như có thể đảm bảo rằng bạn sẽ không có).
Theo cách nói riêng của Apple, keepCount "thường không có giá trị gì trong việc gỡ lỗi các vấn đề quản lý bộ nhớ".
Tất nhiên, bạn không bao giờ nên sử dụng phương thức keepCount trong mã của mình, vì ý nghĩa của giá trị của nó phụ thuộc vào số lượng tự động khôi phục đã được áp dụng cho đối tượng và đó là điều bạn không thể đoán trước được. Tuy nhiên, nó rất hữu ích để gỡ lỗi - đặc biệt là khi bạn đang tìm kiếm lỗi rò rỉ bộ nhớ trong mã gọi các phương thức của đối tượng Appkit bên ngoài vòng lặp sự kiện chính - và nó không nên bị phản đối.
Trong nỗ lực đưa ra quan điểm của mình, bạn đã phóng đại quá mức bản chất khó hiểu của giá trị. Đúng là nó không phải lúc nào cũng là số tham chiếu. Có một số giá trị đặc biệt được sử dụng cho cờ, chẳng hạn để chỉ ra rằng một đối tượng không bao giờ được phân bổ. Một số như 1152921504606846975 trông rất bí ẩn cho đến khi bạn viết nó dưới dạng hex và nhận được 0xfffffffffffffff. Và 9223372036854775807 là 0x7fffffffffffffffff trong hex. Và thực sự không quá ngạc nhiên khi ai đó chọn sử dụng các giá trị như thế này làm cờ, vì sẽ mất gần 3000 năm để có được Số tiền giữ lại cao bằng con số lớn hơn, giả sử bạn tăng Số lượng giữ lại 100.000.000 lần mỗi giây.
Bạn có thể gặp vấn đề gì khi sử dụng nó? Tất cả những gì nó làm là trả về số lượng giữ lại của đối tượng. Tôi chưa bao giờ gọi nó và không thể nghĩ ra bất kỳ lý do gì mà tôi muốn. Tôi đã ghi đè nó trong các đĩa đơn để đảm bảo rằng chúng không bị phân bổ.
retainCount
để quản lý bộ nhớ.
Bạn không nên lo lắng về việc bộ nhớ bị rò rỉ cho đến khi ứng dụng của bạn được thiết lập và chạy và làm điều gì đó hữu ích.
Khi đã có, hãy kích hoạt Instruments và sử dụng ứng dụng và xem liệu tình trạng rò rỉ bộ nhớ có thực sự xảy ra hay không. Trong hầu hết các trường hợp, bạn đã tự tạo một đối tượng (do đó bạn sở hữu nó) và quên giải phóng nó sau khi hoàn tất.
Đừng thử và tối ưu hóa mã của bạn khi bạn đang viết nó, những suy đoán của bạn về những gì có thể làm rò rỉ bộ nhớ hoặc mất quá nhiều thời gian thường sai khi bạn thực sự sử dụng ứng dụng bình thường.
Hãy thử và viết mã chính xác, ví dụ: nếu bạn tạo một đối tượng bằng phân bổ và tương tự, sau đó hãy đảm bảo rằng bạn phát hành nó đúng cách.
-retainCount
.