2009-03-23 10 views
6

Tôi có một ứng dụng iPhone đang nhận được cảnh báo bộ nhớ và vì vậy tôi đang cố gắng tìm rò rỉ, sử dụng bộ nhớ hiệu quả hơn, v.v., với sự trợ giúp của Thiết bị. Trong số những thứ khác, tôi đang cố gắng đưa ra bất kỳ đối tượng autoreleased và thay thế bằng các đối tượng alloc/init/release manual. Tuy nhiên, một số cuộc gọi API dường như không có phiên bản 'init' (xem mã bên dưới). Tôi phải thừa nhận là có một số hiểu lầm cơ bản:Sử dụng các dụng cụ Rò rỉ & Đối tượng Alloc: Các đối tượng tự động được tính là rò rỉ?

  1. Nếu tôi gọi vào 'API và trở lại đối tượng chủ yếu autoreleased, có thể các đối tượng hiển thị như rò rỉ trong Instruments? Dường như tôi thấy hành vi này trong Dụng cụ.

  2. Nếu có đến 2, tôi có nên bỏ qua nếu không có thay thế 'không tự động' và tôi đang sử dụng API mà tôi cần không? Ngoài ra, nếu mã này được gọi là rất nhiều, tôi nên hoàn toàn suy nghĩ lại algor?

Đây là một số mã tiện ích từ ứng dụng của tôi được gọi rất nhiều. Về cơ bản xác định xem hai ngày có ý nghĩa 'bình đẳng' hay không. Tôi đã để lại trong mã nhận xét để bạn có thể thấy các loại cải tiến mà tôi sẽ theo sau trong codebase của mình - DID này giảm rò rỉ bộ nhớ khi chạy trong Instruments khi tôi bắt đầu tạo thủ công NSDate (và phát hành) đã giúp. Tuy nhiên, tôi vẫn có các đối tượng thành phần ngày mà tôi tin là bị rò rỉ ... nhưng đó là cuộc gọi API (xin lỗi vì định dạng mã nhưng tôi dường như không thể cải thiện nó trên SO):

+ (BOOL)isDayEqualToDay:(NSDate*)date anotherDate:(NSDate*)anotherDate 
{ 

    NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 
    //NSCalendar *cal; 
    NSDateComponents *componentsFromDate, *componentsFromAnotherDate; 
    NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;  
    //cal = [NSCalendar currentCalendar]; 
    componentsFromDate = [cal components:unitFlags fromDate:date]; 
    componentsFromAnotherDate = [cal components:unitFlags fromDate:anotherDate]; 

    BOOL bDatesEqual = ([componentsFromDate year] == [componentsFromAnotherDate year] && 
         [componentsFromDate month] == [componentsFromAnotherDate month] && 
         [componentsFromDate day] == [componentsFromAnotherDate day]); 

    [cal release]; 

    return bDatesEqual; 

    /* 
    return (
     [componentsFromDate year] == [componentsFromAnotherDate year] && 
     [componentsFromDate month] == [componentsFromAnotherDate month] && 
     [componentsFromDate day] == [componentsFromAnotherDate day] 
    );*/ 
} 

Tôi nghĩ componentsFromDate và componentsFromAnotherDate được hiển thị dưới dạng rò rỉ nhưng chỉ có các đối tượng về cơ bản được trả về từ một cuộc gọi API NSData (autoreleased). Không chắc chắn những gì khác tôi thực sự có thể làm để làm cho điều này hiệu quả hơn và tôi đang đặt câu hỏi về sự hiểu biết của tôi về cách sử dụng tốt nhất Dụng cụ. Gợi ý?

Trả lời

4

Đối tượng tự động không được hiển thị dưới dạng rò rỉ bộ nhớ. Đôi khi, API có rò rỉ bộ nhớ bên trong chúng. Bạn nên gửi báo cáo lỗi với táo. Các lớp mới như NSCalendar và NSDateComponenets đặc biệt nghi ngờ.

Đối với giữ lại so với tự động trả lại, quy tắc chung là không quan trọng trừ khi bạn đang ở trong vòng lặp chặt chẽ. Trong trường hợp đó, nếu vòng lặp chặt chẽ đang diễn ra nhiều nghìn lần mà không có sự kiện rời đi, điều đó có nghĩa là bạn không bao giờ "dọn dẹp" hồ bơi tự động.

3

Khi sử dụng các công cụ như GCD, có một hồ bơi tự động, nhưng bạn không có cách nào biết được khi nào (nếu bao giờ), kênh tự động thoát nước mặc định sẽ được thoát. Nếu bạn bị thuyết phục rằng các đối tượng không được phát hành không được phát hành, hãy đảm bảo rằng bạn hiểu được api luồng mà bạn đang sử dụng. Nếu bộ nhớ phục vụ cho tôi các cuộc gọi GCD đúng (dispatch_async), hãy sắp xếp các nhóm tự động phát hành cho bạn, NHƯNG việc thoát nước thực sự của hồ bơi có thể mất nhiều thời gian. NSOperations mặt khác cho phép bạn làm cho bạn sở hữu tự động gộp nhóm.

Tôi đã nhìn thấy phát hiện rò rỉ bộ nhớ trong các thiết bị dựa trên khoảng thời gian 10 giây dẫn đến cảnh báo rò rỉ mem sai do sự chậm trễ kéo dài trước khi bể tự động thoát ra. Vì vậy, hãy thử gói mã vi phạm trong:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
... [your code] ... 
[pool drain]; 

Tôi khuyên bạn không nên cố gắng thay thế tất cả các autoreleases bằng các bản phát hành thủ công. Việc sử dụng tính năng tự động trả lại sẽ dẫn đến số lượng cuộc gọi giữ lại/giải phóng ở một vị trí. Tạo một đối tượng và sau đó tự động phát hiện nó ngay lập tức ngăn chặn rất nhiều lỗi bộ nhớ theo ý kiến ​​của tôi. Nhanh chóng, dễ dàng. Bạn sẽ quên phát hành nội dung khi thực hiện bằng cách sử dụng các cuộc gọi phát hành thủ công. Đặc biệt là các điều kiện lỗi là khó khăn khi thực hiện các bản phát hành thủ công.

Làm hồ bơi cho bạn nhiều quyền kiểm soát hơn và trong quá trình phân bổ công việc chuyên sâu đôi khi nó có thể có ích để tạo và thoát hồ bơi của riêng bạn. Nhưng như mọi khi, hãy thử và thử nghiệm, đừng đưa ra bất kỳ giả định nào.

+0

Dường như không có cách nào để sử dụng intstruments để gỡ lỗi GDC. Có cách nào khác không? –