2013-10-08 13 views
5

Tôi đang sử dụng ARC và sự cố ứng dụng cho biết cảnh báo bộ nhớ nhận được. Tôi đang thử nghiệm ứng dụng trực tiếp trên thiết bị (iPhone 4 với iOS 7.0.2) và biên dịch bằng XCode 5 bằng SDK iOS 6. Tôi đã sử dụng các công cụ táo và tôi đang có khoảng 20MB LiveBytes được phân bổ.Cách gỡ lỗi sự cố iOS do áp lực bộ nhớ

App at start

Sau 4-5 phút ứng dụng của tôi có 30MB bộ nhớ.

App status after 5 min

Sau khi biên soạn và thử nghiệm các ứng dụng trên thiết bị của tôi nhìn thấy tai nạn mà sau một vài phút, ngay sau khi thông điệp cảnh báo bộ nhớ. Tại sao không xảy ra tai nạn bằng dụng cụ? Tuy nhiên tôi đang cố gắng giải quyết vấn đề này trong một tháng và không thể có được sự nghi thức, và tôi thực sự cần sự giúp đỡ. Có vẻ như tôi không có bất kỳ rò rỉ nào nhưng tôi không thể tìm thấy nơi nào sai. Cảm ơn trước vì lời khuyên nào.

+0

Tôi có một ứng dụng hoạt động tốt trên iPad 2 ... cho đến khi tôi nâng cấp lên iOS 7, giờ nó bị lỗi do 'áp lực bộ nhớ'. Bạn đã tìm ra cách giải quyết vấn đề này? – j9suvak

+0

Tôi có cùng một vấn đề, có thể đăng câu hỏi khác sớm nếu tôi không thể tìm thấy câu trả lời ở nơi khác. – MattLoszak

+1

Tôi đã giải quyết được sự cố của mình, hãy kiểm tra câu trả lời của tôi. – andreapavan

Trả lời

3

Tôi đã giải quyết được sự cố. Trong trường hợp của tôi, áp lực bộ nhớ, đó là do việc sử dụng bộ nhớ liên tục bởi một chu trình vòng lặp chạy. Vòng lặp được thực thi mỗi giây và hoạt động trên dữ liệu phải được phân tích và trình bày trong các khung nhìn. Một điều nữa, dự án ban đầu không sử dụng ARC. Sau khi một dự án chuyển đổi sang ARC đã xảy ra sự cố.

Trước khi chuyển đổi dự án thành ARC, vào cuối vòng lặp, tôi đã có cuộc gọi trực tiếp để giải phóng tài nguyên. Với ARC tất nhiên điều này được thực hiện tự động, và vấn đề là chỉ có vậy. Vì vậy, đối với lớp chạy vòng lặp, tôi đã quay lại phiên bản không phải ARC và tôi đã sử dụng các thủ thuật để thực hiện thủ công để giải phóng tài nguyên mà tôi đã sử dụng.

Khối bể tự động cung cấp cơ chế theo đó bạn có thể từ bỏ quyền sở hữu đối tượng, nhưng tránh khả năng bị xử lý ngay lập tức (chẳng hạn như khi bạn trả về đối tượng từ phương thức). Thông thường, bạn không cần phải tạo các khối nhóm tự động phát hành riêng của mình, nhưng có một số tình huống mà bạn phải hoặc có lợi khi làm như vậy.

@autoreleasepool { 
    // Code that creates autoreleased objects. 
} 

Vào cuối của khối autorelease hồ bơi, các đối tượng đã nhận được một thông báo autorelease trong khối được gửi một thông điệp một bản phát hành đối tượng nhận được một thông điệp phát hành cho mỗi lần nó đã được gửi một thông báo autorelease trong khối.

Bạn có thể đặt một khối @autoreleasepool xung quanh bất kỳ phần nào của mã, tuy nhiên bạn thực sự không nên làm những gì tôi nghĩ bạn đang làm.

Tự động trả tiền kém hiệu quả hơn nhiều so với việc cho phép ARC thêm vào giữ lại và giải phóng cuộc gọi cho bạn và có khả năng không an toàn. Autorelease đặt tất cả các đối tượng của bạn trong một "hồ bơi" và sau đó khi bạn ra khỏi phạm vi và/hoặc bất cứ khi nào nó quyết định đổ hồ bơi, nó "thoát" hồ bơi và số lượng giữ lại của đối tượng được giảm đi một.

Câu trả lời ngắn: Bỏ qua các khối tự động hoàn toàn trừ khi Apple nói cách khác trong tài liệu hoặc mẫu (ví dụ: main.m sẽ có @autoreleasepool trong đó).

Điều này có nghĩa là các đối tượng của bạn có thể có khả năng được phát hành trước khi bạn thực sự muốn chúng. Các khối @autoreleasepool hữu ích hơn khi bạn có một vòng lặp mã rất chặt chẽ và sẽ loại bỏ một lượng lớn các đối tượng. Ví dụ, một vòng lặp for xử lý một cơ sở dữ liệu khổng lồ và phân bổ các đối tượng chuỗi và sau đó sử dụng các đối tượng chuỗi đó để điền vào các thuộc tính của các cá thể của một lớp mà bạn đã tạo ra.Trong trường hợp này, ARC có thể không giải phóng các đối tượng đó một cách đáng tin cậy khi bạn đang ở trong vòng lặp for và bạn có thể cần phải tạo một nhóm tự động phát hành.

Tuy nhiên, ARC không làm điều đúng trong một vòng lặp chặt chẽ không phải là rất phổ biến. Nó thực sự là một khái niệm không phải ARC, nơi bạn sử dụng NSAutoreleasePool và bạn tự rút nó ra.

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-CJBFBEDI

Tôi hy vọng tôi đã giúp những người khác có cùng vấn đề.

+1

Tôi nghĩ rằng bạn đã đi đến một kết luận không chính xác ở đây, '@ autoreleasepool's vẫn hữu ích trong ARC và không chỉ trong các vòng lặp chặt chẽ. Tôi đã thấy trợ giúp '@ autorelease' với các vấn đề về áp lực bộ nhớ trong ứng dụng của tôi khi xử lý các vòng lặp I/O bộ nhớ lớn bên ngoài. Ngoài ra: http://stackoverflow.com/questions/9086913/objective-c-why-is-autorelease-autoreleasepool-still-needed-with-arc – Shizam

+1

@andreapavan. tôi có cùng một vấn đề. tôi có bản ghi 5k từ dịch vụ web hơn tôi đang chèn tất cả bản ghi này vào db. Mỗi lần ghi 3k thành công được chèn vào ứng dụng. Vòng lặp của tôi sẽ chạy 5k thời gian khi tôi chèn bản ghi 5k. như vậy là nó tốt để thực hiện phương pháp autoreleasepool trong vòng lặp? – Hitarth

+0

Tôi là một trường hợp khá đặc biệt bởi vì tôi phải có được bàn tay của tôi trên một dự án được phát triển theo nhiều bước. Như đã nói, Shizam, autoreleasepools cũng hữu ích nếu bạn sử dụng ARC. Thông thường, bạn không cần phải tạo các khối hồ bơi tự động phát của riêng mình, nhưng có một số tình huống mà bạn phải hoặc là có lợi khi làm như vậy. Tôi đã có một vấn đề giữa ARC và autoreleasepool khối. Trong thực hiện cũ, điều này đã được xử lý bằng tay, và tôi giữ như vậy. Tôi chỉ ra trong các thiết lập mà lớp không sử dụng ARC và tôi quản lý bộ nhớ bằng tay bằng cách sử dụng một khối autoreleasepool khi cần thiết. – andreapavan

0
#pragma mark - Received Memory Warning 

//memory pressure ios 
- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 

    if ([self isViewLoaded] && self.view.window == nil) 
    { 
     self.view = nil; 
    } 

    // Dispose of any resources that can be recreated. 
} 
Các vấn đề liên quan