2010-03-04 40 views
7

Tôi sử dụng các công cụ để xem rò rỉ bộ nhớ. Ít nhất trong một kịch bản mà tôi liên tục flicking thông qua các slide/trang (bên trong UIScrollView) Tôi không thấy bất kỳ rò rỉ bộ nhớ. Sử dụng nhạc cụ - trong "Tuổi thọ phân bổ", tôi chuyển sang chế độ xem "Đã tạo & Vẫn sống" và xem bộ nhớ trong khoảng 1,17MB trong suốt. Tôi cho rằng điều này có nghĩa là ứng dụng của tôi chỉ sử dụng bộ nhớ thực tế này và phần còn lại đang được tái chế đúng cách.Cảnh báo và sự cố bộ nhớ: cách xử lý nó

Tuy nhiên, sau khi lướt qua 100 trang trở lên, tôi nhận được cảnh báo bộ nhớ và sau đó vài lượt xem của tôi bị hủy tải dẫn đến sự cố xảy ra trong toàn bộ ứng dụng.

Nếu tôi không sử dụng nhiều bộ nhớ và không bị rò rỉ bộ nhớ, tại sao tôi nhận được cảnh báo bộ nhớ? Vì không có gì tôi thực sự có thể giải phóng nên tôi không thấy cách nào để tránh tai nạn. Bất cứ ai đã trải nghiệm tình huống này hoặc biết tôi có thể làm gì? Tôi có hiểu sai điều gì từ Dụng cụ không? Cảm ơn nhiều vì bất kỳ bình luận nào.

+0

Không đầu mối vẫn. Có lẽ 'Dụng cụ' không báo cáo đúng một số rò rỉ mà tôi có thể có. Có công cụ tìm kiếm rò rỉ bộ nhớ nào khác đáng tin cậy hơn không? – climbon

Trả lời

11

The documentation says:

Nếu một đối tượng hình ảnh phù hợp không phải là đã có trong bộ nhớ cache, phương pháp này sẽ tải dữ liệu hình ảnh từ một file nào đó, lưu trữ nó, và sau đó trả về đối tượng kết quả.

Do đó, mọi hình ảnh bạn tải bằng cách sử dụng imageNamed: sẽ tiếp tục tồn tại trong bộ nhớ cache sau khi bạn phát hành quyền sở hữu cuối cùng của nó.

Thiết bị không hiển thị điều này dưới dạng rò rỉ bởi vì, nói đúng, nó không phải là một thứ: Thứ gì đó (UIImage) vẫn biết về những hình ảnh này. Công cụ Rò rỉ sẽ chỉ hiển thị một rò rỉ cho một đối tượng tồn tại nhưng không có gì biết.

Bạn vẫn có thể thấy điều này trong Dụng cụ.

  1. Chọn công cụ ObjectAlloc trong tài liệu theo dõi của bạn và sắp xếp danh sách các lớp theo số lượng hiện tại hoặc theo tổng kích thước hiện tại. Bạn sẽ thấy rằng phần lớn bộ nhớ bị chiếm bởi các đối tượng UIImage.
  2. Nếu bạn di chuột qua cột tên lớp cho hàng UIImage, bạn sẽ thấy biểu tượng ➲ (go-to-iTunes-Store); nếu bạn nhấp vào đó, bạn sẽ thấy danh sách tất cả các phiên bản UIImage của bạn.
  3. Sau đó, nếu bạn di chuột qua cột địa chỉ cho hàng của một đối tượng, bạn sẽ thấy cùng một nút; thời gian này, nhấp vào nó sẽ đưa bạn đến lịch sử của địa chỉ đó, bao gồm tất cả các sáng tạo, retentions, phát hành, và deallocations của các đối tượng với địa chỉ đó.

    Ở đây, bạn có thể xem phân bổ của hình ảnh (trong lớp UIImage, được sắp xếp bởi bạn một vài ngăn xếp xuống), lưu giữ (bởi bạn) và phát hành (bởi bạn). Bạn cũng có thể thấy rằng nó chưa được phát hành bởi UIImage - bộ nhớ cache +[UIImage imageNamed:] vẫn sở hữu hình ảnh, do đó "rò rỉ".

Nếu bạn không muốn hình ảnh để chồng chất lên như thế, tải chúng mình sử dụng imageWithContentsOfFile:the -[NSBundle pathForResource:ofType:] method.

CẬP NHẬT: Tôi đã đọc rằng kể từ iOS 3, UIImage sẽ xóa bộ nhớ cache trong ít nhất một số tình huống bộ nhớ thấp, vì vậy điều này sẽ không nhiều "rò rỉ" như trước đây. Có thể bạn vẫn sẽ thấy bộ nhớ chồng chất lên, nhưng sau đó bạn sẽ thấy sự sụp đổ đống cuối cùng. Nếu bạn vẫn thấy bộ nhớ chồng chất lên và có thể chứng minh rằng đó là lỗi của Apple, bạn nên ghi lại bằng chứng của mình và file a bug.

+0

Một triệu lần CẢM ƠN BẠN! – RanLearns

0

Tìm thấy nguồn gốc của vấn đề. Đó là trong đoạn mã sau

UIImage *image = [UIImage imageNamed:imageFile]; 

cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)]; 

cartoon.image = image ; 
cartoon.backgroundColor = [UIColor brownColor]; 

Tôi có 100 hình ảnh cùng với một số văn bản trên mỗi trang và người dùng có thể cuộn qua chúng bằng ngón tay (giống như trong ứng dụng ảnh của iphone). Tôi chỉ tạo 3 trang trong UIScrollView của tôi và tải/unload (và cũng phát hành) tất cả mọi thứ mà tôi phân bổ một cách rõ ràng. Vì vậy, khi nói đến việc phát hành phim hoạt hình tôi chỉ đơn giản là phát hành phim hoạt hình UIImageView và không phải là UIImage nghĩ rằng nó sẽ được tự động phát hành.

Nhưng có vẻ như nó không được tự động phát hành. Ứng dụng của tôi nhận được cảnh báo bộ nhớ (tôi không thực hiện bất kỳ hành động nào) và hệ điều hành dỡ bỏ lượt xem của tôi gây ra sự cố.

Khi tôi nhận xét hai dòng (đoạn mã được sửa đổi bên dưới), sự cố sẽ biến mất. Không có cảnh báo không có sự cố.

//UIImage *image = [UIImage imageNamed:imageFile]; 

cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)]; 

//cartoon.image = image ; 
cartoon.backgroundColor = [UIColor brownColor]; 

Có ai biết cách giải quyết vấn đề này không? Có cách nào để buộc bộ nhớ phát hành khỏi UIImage khi cảnh báo xảy ra không?

+0

Nó đang được tự động phát hành. Nó cũng chỉ thuộc sở hữu của một cái gì đó khác. Bạn có thể thấy điều này bằng cách xem các cá thể UIImage riêng lẻ trong Công cụ. –

2

Bạn có biến môi trường NSZombieEnabled được đặt thành có không? Nó sẽ gây ra các đối tượng deallocated để tồn tại trong bộ nhớ, do đó không cho phép bạn lấy lại bộ nhớ. Vì vậy, hãy thử vô hiệu hóa nó, nếu hoạt động.

1

Bạn đã kiểm tra phát hành tất cả các đối tượng IBOutlet chưa? Trên dealloc của bạn, bạn nên phát hành bất kỳ đối tượng IBOutlet bạn có trong đối tượng của bạn, ngay cả khi họ không có một phương pháp tổng hợp.

Chúng tôi có vấn đề tương tự và chúng tôi đã giải quyết vấn đề phát hành tất cả IBOutlets.

Check this answer in Stack Overflow

1

Nếu bạn chỉ có 3 trang Tôi hiểu rằng bạn đang sử dụng lại một số mặt hàng.

Nếu không có phần còn lại của mã, rất khó để nói những gì đang xảy ra, nhưng có lẽ bạn nên cố gắng giải phóng đối tượng hoạt hình trước khi tạo đối tượng mới.

Hãy thử một cái gì đó như thế này:

IImage *image = [UIImage imageNamed:imageFile]; 

if (cartoon!=nil) 
    [cartoon release]; 

cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)]; 

cartoon.image = image ; 
cartoon.backgroundColor = [UIColor brownColor]; 
Các vấn đề liên quan