2010-06-28 39 views
6

Cập nhật: rò rỉ này đã được giải quyết. Nếu bạn đang nhận được rò rỉ tương tự và ứng dụng của bạn là đa luồng, bạn có nhiều khả năng thực hiện cuộc gọi UIKit từ một chuỗi nền; tận dụng ví dụ [NSThread performSelectorOnMainThread:] để định tuyến các cuộc gọi UIKit tới chủ đề chính, lànơi duy nhất được phép.Rò rỉ (cụ) báo cáo rò rỉ trong các đối tượng tự động phát hiện

Tôi đã chạy Rò rỉ trong dự án hiện tại của mình để tìm rò rỉ gần đây, và tôi tiếp tục chạy vào những "rò rỉ" mà từ những gì tôi có thể nói không thực sự bị rò rỉ. Các mã sau đây, lấy trực tiếp từ dự án, có hai rò rỉ, theo Rò rỉ:

- (NSArray *)areaForIndex:(int)index 
{ 
    NSMutableArray *a = [NSMutableArray arrayWithArray: 
     [world retrieveNeighborsForIndex:index]]; // leak 1 
    [a insertObject:[references objectAtIndex:index] atIndex:0]; 
    return [NSArray arrayWithArray:a]; // leak 2 
} 

Leak 1 sẽ biến mất nếu tôi thay đổi dòng đầu tiên: (xem Cập nhật 2-3)

Rò rỉ 2 biến mất nếu tôi thay đổi dòng cuối cùng thành:

return a; 

Tôi không may làm điều đó với rò rỉ 1 vì tôi đang đúc một mảng bất biến thành mảng có thể thay đổi. Tuy nhiên, arrayWithArray có nghĩa vụ phải tự động phát hành, dù sao, vì vậy từ những gì tôi có thể nói, nó sẽ không bị rò rỉ bất cứ điều gì. Có ý kiến ​​giải thích tại sao điều này lại xảy ra không?

Cập nhật: Tôi đã thử nghiệm điều này trên cả thiết bị và Trình mô phỏng. Rò rỉ có trên cả hai. Tuy nhiên, trên Simulator tôi nhận được thêm một số thông tin về rò rỉ này:

Lịch sử cho rò rỉ diễn ra như sau:

# | Category | Event Type | Timestamp | RefCt | Address | Size | Responsible Library | Responsible Caller 
--+----------+-------------+ 
0 | CFArray | Malloc  | 00:09.598 |  1 | 0x474f6d0 | 48 | asynchro   | -[muddyGrid areaForIndex:] 
1 | CFArray | Autorelease | 00:09.598 |  | 0x474f6d0 | 0 | Foundation   | NSRecordAllocationEvent 
2 | CFArray | CFRetain | 00:09.598 |  2 | 0x474f7d0 | 0 | Foundation   | -[NSCFArray retain] 
3 | CFArray | CFRelease | 00:09.611 |  1 | 0x474f7d0 | 0 | Foundation   | NSPopAutoreleasePool 

Những điều tôi có thể phân biệt từ trên được rằng mảng autoreleased được bằng cách nào đó giữ lại hai lần và sau đó autoreleased, để lại giữ lại đếm tại 1. Không có ý tưởng nơi hoặc tại sao mặc dù ...

cập nhật 2 & 3: tôi đã cố gắng thay đổi dòng cho rò rỉ từ 1 tới:

NSMutableArray *a = [[[NSMutableArray alloc] initWithArray: 
     [world retrieveNeighborsForIndex:index]] autorelease]; 

Tôi nghĩ rằng điều này đã loại bỏ sự rò rỉ, nhưng cuối cùng thì không. Vì vậy, tôi vẫn thua lỗ.

+0

Bạn có đang thử nghiệm trên thiết bị hoặc trình mô phỏng không? – rickharrison

+0

Hiện chỉ có trên thiết bị. Nhưng bạn nói đúng, tôi sẽ kiểm tra và xem nó như thế nào trên Trình mô phỏng và cập nhật. – Kalle

+0

Cập nhật mô tả ở trên để bao gồm những gì tôi đã tìm được từ việc thử nó trên Trình mô phỏng. Cảm ơn con trỏ! :) – Kalle

Trả lời

2

Anticlimactically, điều này tự giải quyết khi tôi giải quyết một loạt các vấn đề khác với mã của tôi.

Chủ yếu, mã có một số vị trí nơi cập nhật giao diện người dùng được tạo bên ngoài luồng chính, đó là số không lớn. Một trong những vấn đề không liên quan khác phải kích hoạt rò rỉ bộ nhớ trong đoạn mã trên, vì nó không báo cáo bất kỳ rò rỉ nữa (tôi có 0 rò rỉ khi nó đứng), mặc dù tôi chưa sửa đổi mã bất kỳ.

0

Điều gì retrieveNeighborsForIndex trả về?

Có khả năng kết quả của phương pháp này được giữ lại (không được tự động phát hành) không?

+0

Nó trở về [hàng xóm allObjects], nơi hàng xóm là một NSMutableSet chứa một số đối tượng (9-12). – Kalle

-1

arrayWithArray giữ lại các đối tượng bạn đã lưu trữ trong mảng có thể thay đổi. http://www.iphonedevsdk.com/forum/iphone-sdk-development/14285-nsmutablearray-arraywitharray-does-add-retain.html

Tôi khuyên bạn nên phát hành nó hoặc an toàn hơn nhưng tạo đối tượng bằng bộ thuộc tính tự động phát hành. Khi gọi các quốc gia hàng xóm đang chạy thử để lập chỉ mục, hãy tự động phát hành các đối tượng đó và chúng sẽ được giải phóng khi mảng không thể cắt được được giải quyết

EDIT: Một mẹo tôi có thể thêm khi theo dõi lỗi bộ nhớ là kích hoạt zombie và kiểm tra số tham chiếu đối tượng của bạn. Sau đó bạn có thể xác định cái nào không được phát hành và nó sẽ giúp việc theo dõi của bạn dễ dàng hơn. Liên kết này sẽ chỉ cho bạn cách thiết lập dự án xcode của bạn để kích hoạt zombie: cocoadev.com/index.pl?NSZombieEnabled

+0

Nó có, nhưng mảng được trả về bởi 'arrayWithArray:' là chính nó được tự động phát hành, vì vậy việc tự giải phóng nó có lẽ sẽ gây ra sự cố. Điều đó nói rằng, nó có thể an toàn để trả lại các mảng mutable chính nó, kể từ khi bạn đang tạo nó và trả lại nó trong cùng một phương pháp, không có tác dụng phụ ẩn. – Wevah

+0

Điều đó làm việc cho rò rỉ 2 (và đó là những gì tôi đang làm bây giờ), nhưng nó không giải quyết rò rỉ 1, nơi tôi lấy một mảng bất biến thành một mảng có thể thay đổi bằng arrayWithArray, vì tôi cần phải thêm vào nó trước khi trở về nó. – Kalle

+0

Phản ứng của tôi đối với Wevah, nhân tiện; Shadow's right trong đó 'arrayWithArray:' giữ lại các đối tượng trong mảng, nhưng bản thân nó không được chứa và không được phát hành cũng như không được tự động phát hành. – Kalle

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