2011-12-16 25 views
8

Tôi vẫn đang cố gắng hiểu đoạn mã mà tôi tìm thấy trong một dự án mà tôi đang làm việc ở nơi người tạo ra nó rời công ty trước khi tôi có thể hỏi.Bạn nghĩ gì về mã này trong Mục tiêu-C làm tăng số lần giữ lại của thorugh và gọi mỗi lần lặp lại?

Đây là mã:

-(void)releaseMySelf{ 
    for (int i=myRetainCount; i>1; i--) { 
     [self release]; 
    } 
    [self autorelease]; 
} 

Theo như tôi biết, trong Objective C mô hình quản lý bộ nhớ, quy tắc đầu tiên là các đối tượng mà phân bổ đối tượng khác, cũng có trách nhiệm để phát hành nó trong Tương lai. Đó là lý do tôi không hiểu ý nghĩa của mã này. Có ý nghĩa gì không?

+4

Tôi nghĩ "Bò thánh!" – albertamg

+20

Không có gì ngạc nhiên khi anh rời công ty; mã như thế là một dấu hiệu chắc chắn rằng anh ta đang đi ngang qua đầu mình, không hiểu cách viết một ứng dụng và không có cơ hội để học những cách thích hợp. Nếu tôi thấy rằng trong một dự án (và tôi đã sử dụng một công ty dịch vụ tư vấn đã "dọn dẹp" trên các dự án gặp khó khăn), tôi sẽ ngay lập tức ném một lá cờ đỏ và yêu cầu mọi dòng mã được viết bởi người đó . (Nó cũng có vẻ như anh ta đang duy trì số lượng riêng biệt với số lượng thực tế của đối tượng ... 2 lá cờ đỏ trong vở kịch đó.) – bbum

+9

Tôi nghĩ rằng "Tôi muốn biết ai đã viết điều đó để tôi có thể chắc chắn không bao giờ làm việc với anh ấy " –

Trả lời

17

Tác giả đang cố gắng làm việc xung quanh không hiểu quản lý bộ nhớ. Ông giả định rằng một đối tượng có số lượng giữ lại được tăng lên bởi mỗi lần giữ lại và do đó cố gắng giảm nó bằng cách gọi số lượng bản phát hành đó. Có lẽ ông đã không thực hiện "cũng chịu trách nhiệm giải phóng nó trong tương lai." một phần của sự hiểu biết của bạn.

Tuy nhiên, hãy xem nhiều câu trả lời tại đây, ví dụ: hereherehere.

Đọc Apple's memory management concepts.

Các liên kết đầu tiên bao gồm một trích dẫn từ Apple

Phương pháp retainCount không chiếm bất kỳ autorelease cấp phát thông điệp gửi đến người nhận.

Quan trọng: Phương pháp này thường không có giá trị trong việc gỡ lỗi bộ nhớ sự cố quản lý. Bởi vì bất kỳ số lượng đối tượng khung có thể có giữ lại một đối tượng để giữ tham chiếu đến nó, trong khi tại cùng một thời gian autorelease hồ bơi có thể giữ bất kỳ số lượng hoãn lại bản phát hành trên một đối tượng, nó rất khó mà bạn có thể nhận được hữu ích thông tin từ phương pháp này. Để hiểu các quy tắc cơ bản của quản lý bộ nhớ mà bạn phải tuân theo, hãy đọc “Quản lý bộ nhớ Quy tắc”. Để chẩn đoán các vấn đề về quản lý bộ nhớ, hãy sử dụng một công cụ phù hợp: Máy phân tích tĩnh LLVM/Clang thường có thể tìm thấy các vấn đề quản lý bộ nhớ ngay cả trước khi bạn chạy chương trình. Thiết bị Object Alloc trong ứng dụng Công cụ (xem Hướng dẫn sử dụng thiết bị) có thể theo dõi việc phân bổ và tiêu hủy đối tượng . Shark (xem Hướng dẫn sử dụng Shark) cũng phân bổ bộ nhớ hồ sơ (trong số rất nhiều khía cạnh khác của chương trình ).

+3

Trên một lưu ý phụ, tôi khuyên bạn nên loại bỏ đoạn mã này và chạy mã của bạn thông qua phân tích tĩnh. Nó sẽ hiển thị nơi các đối tượng nên được phát hành. – Eimantas

3

Đây là một hack bẩn để buộc phát hành bộ nhớ: nếu phần còn lại của chương trình của bạn được viết chính xác, bạn không bao giờ phải làm bất cứ điều gì như thế này. Thông thường, bạn giữ lại và phát hành là trong sự cân bằng, vì vậy bạn không bao giờ cần phải nhìn vào số lượng giữ lại. Những gì đoạn mã này nói là "Tôi không biết ai giữ lại tôi và quên để phát hành, tôi chỉ muốn bộ nhớ của tôi để có được phát hành, tôi không quan tâm rằng các tài liệu tham khảo khác sẽ được lúng túng từ bây giờ". Điều này sẽ không biên dịch với ARC (đủ kỳ quặc, việc chuyển sang ARC có thể chỉ sửa lỗi mà tác giả đang cố gắng làm việc).

2

Ý nghĩa của mã là buộc đối tượng phải giải quyết ngay bây giờ, bất kể hậu quả trong tương lai có thể là gì. (Và sẽ có hậu quả!)

Mã này không hợp lệ vì không tính đến thực tế là một người nào đó thực sự "sở hữu" đối tượng đó. Nói cách khác, một cái gì đó "phân bổ" đối tượng đó và bất kỳ số thứ nào khác có thể "giữ lại" đối tượng đó (có thể là cấu trúc dữ liệu như NSArray, có thể là một nhóm tự động, có thể một số mã trên stackframe chỉ làm "giữ lại"); tất cả những thứ đó đều có chung quyền sở hữu đối tượng này. Nếu đối tượng tự sát (đó là những gì releaseMySelf làm), những "chủ sở hữu" đột nhiên trỏ đến bộ nhớ xấu, và điều này sẽ dẫn đến hành vi bất ngờ.

Hy vọng rằng mã được viết như thế này sẽ chỉ bị lỗi. Có lẽ tác giả gốc đã tránh được những sự cố này bằng cách rò rỉ bộ nhớ ở nơi khác.

+1

Cảm ơn rất nhiều bạn! Đó là những gì tôi nghĩ, đây là một mã khủng khiếp. – Ricardo

7

Vì tất cả các câu trả lời dường như đã hiểu sai myRetainCount như [self retainCount], hãy để tôi đưa ra lý do tại sao mã này có thể được viết: Có thể mã này bằng cách nào đó sinh ra chủ đề hoặc có khách hàng đăng ký với nó myRetainCount là số lượng khách hàng hiệu quả, được giữ riêng biệt với số lượng hệ điều hành thực tế được giữ lại. Tuy nhiên, mỗi khách hàng cũng có thể có được phong cách ObjC riêng của mình.

Vì vậy, chức năng này có thể được gọi trong trường hợp yêu cầu bị hủy và có thể xử lý tất cả các khách hàng cùng một lúc và sau đó thực hiện tất cả các bản phát hành. Nó không phải là một thiết kế tốt, nhưng nếu đó là cách mã hoạt động, (và bạn đã không bỏ ra một int myRetainCount = [self retainCount], hoặc ghi đè của giữ lại/phát hành) ít nhất nó không nhất thiết phải lỗi.

Đó là, tuy nhiên, rất có thể là một phân phối xấu của trách nhiệm hoặc một kludgey và hackneyed cố gắng tránh các vòng tròn mà không thực sự cải thiện bất cứ điều gì.

+0

Tuy nhiên nó vẫn không phải là cách chính xác để thực hiện - nó vẫn là tác giả không nhận được quản lý bộ nhớ chính xác - giữ lại/phát hành vv làm việc với các chủ đề – Mark

+0

Chủ đề chỉ có nghĩa là một ví dụ của khách hàng mà một trong những thường sẽ đăng ký/unregister, ví dụ cho các nhóm luồng hoặc hành vi "hủy tất cả". – uliwitness

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