Helpex - Trao đổi & giúp đỡ Đăng nhập
19

Tôi đã gặp một số vấn đề về bộ nhớ do mẫu của Xcode cho một UIPageViewController lưu vào bộ nhớ đệm tất cả dữ liệu trang, vì vậy tôi đã thay đổi nó để tải động các trang, vì vậy bây giờ khi ứng dụng của tôi nhận được cảnh báo bộ nhớ thấp, nó sẽ giải phóng bộ nhớ để trang không hiển thị, nhưng nếu người dùng đang lướt qua các trang thật nhanh bằng cách chạm vào cạnh của màn hình, nó vẫn bị treo. Tôi đoán điều này là do nó không thể giải phóng bộ nhớ đủ nhanh khi didReceiveMemoryWarning được gọi. Nếu người dùng lật chậm, nó hoạt động tốt. Tôi đã giới hạn tốc độ mà người dùng có thể lật trang, nhưng nó vẫn xảy ra. Tôi muốn có thể giải phóng bộ nhớ mỗi khi lật trang và không phải đợi cảnh báo bộ nhớ thấp. Tôi đang sử dụng ARC. Có cách nào để làm việc này không? Hoặc tôi có thể làm gì khác để ngăn chặn điều này? Cảm ơn.

BIÊN TẬP:

(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    NSUInteger index = [self indexOfViewController:(SinglePageViewControllerSuperclass *)viewController];
    if ((index == 0) || (index == NSNotFound)) {
        return nil;
    }

    index--;
    return [self viewControllerAtIndex:index];
} 

(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    NSUInteger index = [self indexOfViewController:(SinglePageViewControllerSuperclass *)viewController];
    if (index == NSNotFound || index == MAX_PAGE_INDEX) {
        return nil;
    }

    return [self viewControllerAtIndex:++index];
}
19 hữu ích 2 bình luận 10k xem chia sẻ
5

Tôi nghĩ rằng giả thuyết của bạn là đúng, vì tôi cũng đã trải qua một hành vi tương tự: khi bạn lật sang trang tiếp theo, cũng vì mục đích làm sinh động mọi thứ một cách dễ dàng, trang mới được phân bổ trước khi trang cũ được phân bổ và phải mất một số lần cho cái cũ sẽ được phân bổ. Vì vậy, khi bạn lật đủ nhanh, các đối tượng được phân bổ nhanh hơn chúng được phân bổ và cuối cùng (thực sự là khá sớm), ứng dụng của bạn bị giết do sử dụng bộ nhớ. Độ trễ phân bổ thỏa thuận khi lật trang trở nên khá rõ ràng nếu bạn theo dõi phân bổ / phân bổ bộ nhớ trong Instruments.

Bạn có ba cách tiếp cận cho điều này, IMO:

  1. triển khai viewDidLoadphương thức "nhẹ" (thực tế là toàn bộ trình tự khởi tạo / hiển thị ban đầu): trong một số ứng dụng, có ý nghĩa, ví dụ: tải hình ảnh có độ phân giải thấp thay vì hình ảnh có độ phân giải cao sẽ được hiển thị; hoặc, hơi trì hoãn việc phân bổ các tài nguyên bổ sung mà trang của bạn cần (quyền truy cập db, âm thanh, v.v.);

  2. sử dụng một nhóm các trang, chẳng hạn như một mảng gồm ba trang (hoặc 5, tùy thuộc vào ứng dụng của bạn), mà bạn tiếp tục "tái sử dụng" để cấu hình bộ nhớ của ứng dụng của bạn vẫn ổn định và tránh tăng đột biến;

  3. xem xét cẩn thận cách bạn phân bổ và giải phóng bộ nhớ; theo nghĩa này, bạn thường đọc rằng tự động phát hành thêm một số "quán tính" vào cơ chế phát hành / phân bổ và điều này khá dễ hiểu: nếu bạn có một đối tượng được phát hành tự động, nó sẽ được giải phóng bởi nhóm phát hành của nó chỉ khi bạn chuyển qua vòng lặp chính (điều này đúng với nhóm phát hành chính); vì vậy, nếu bạn có một chuỗi dài các phương thức được gọi khi lật trang, điều này sẽ làm cho việc phát hành / dealloc xảy ra sau đó.

Không có gì kỳ diệu khi nói đến tối ưu hóa việc sử dụng bộ nhớ, đó là một công việc khá chi tiết và khó khăn, nhưng IME bạn sẽ có thể giảm cấu hình bộ nhớ của ứng dụng nếu bạn xem lại mã của mình và áp dụng 3 nguyên tắc đó. Đặc biệt, việc kiểm tra mức tăng đột biến của phân bổ bộ nhớ trong Instruments và cố gắng hiểu những gì chúng liên quan là vô cùng mạnh mẽ.

5 hữu ích 1 bình luận chia sẻ
2

Đây là một thay đổi bổ sung mà tôi đã thực hiện mà ai đó có thể thấy hữu ích:

Về cơ bản, tôi chỉ cho phép một trang mới bắt đầu nếu trang trước đó đã kết thúc.

Tôi đang sử dụng dự án PageViewController mặc định của apple làm mẫu nên tôi sẽ sử dụng các thuật ngữ được xác định trong dự án đó.

Bất cứ khi nào VC của trang được yêu cầu thông qua viewControllerAtIndex :, tôi đặt một giá trị boolean trên ModelController được gọi là ' shouldDenyVC' thành YES.

Trong EbookViewController của tôi là đại biểu của UIPageViewController, tôi nắm bắt các trình nhận dạng cử chỉ và chỉ định EbookViewController làm đại biểu của chúng:

self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;
for (UIGestureRecognizer *gr in self.view.gestureRecognizers) {
    gr.delegate = self;
}

Sau đó, tôi có thể từ chối chuyển trang bằng cách từ chối các trình nhận dạng cử chỉ:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:    (UITouch *)touch
{
    if (_modelController.shouldDenyPageTurn == YES) {
        return FALSE;
    }
    return TRUE;
}

Và cuối cùng, tôi đặt _modelController.shouldDenyPageTurn = NOở cuối phương thức ủy quyền UIPageViewControllerpageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:

Tôi cũng phải đặt _modelController.shouldDenyPageTurn = NOở cuối bất kỳ tải trước nào để lượt trang được phép tắt.

2 hữu ích 0 bình luận chia sẻ
0

Hiện tại, có một lỗi trong iOS5 khiến chế độ xem cuộn bị rò rỉ một lượng nhỏ bộ nhớ.

Bạn đã thử lập hồ sơ ứng dụng của mình trong các công cụ kiểm tra phân bổ và rò rỉ bộ nhớ chưa?

Bạn có thể mô phỏng cảnh báo bộ nhớ thấp trong trình mô phỏng (phần cứng -> mô phỏng cảnh báo bộ nhớ thấp). Hoặc bạn có thể làm điều đó thông qua mã, (chỉ cần nhớ xóa sau khi gỡ lỗi vì điều này sẽ khiến ứng dụng của bạn bị từ chối!)

[[UIApplication sharedApplication] performSelector:@selector(_performMemoryWarning)];

Nếu bạn đang sử dụng stronghoặc retaincác thuộc tính, hãy đặt chúng thành nilsau khi bạn hoàn thành với chúng và ARC sẽ giải phóng bộ nhớ mà chúng đang trỏ tới đằng sau hậu trường.

Nếu bạn đang tạo nhiều đối tượng tạm thời (đối tượng không phải là thuộc tính hoặc không được cấp phát) thì hãy chèn một nhóm tự động khôi phục:

@autoreleasepool {

}

Và cuối cùng, hãy hiển thị một số mã và chúng tôi có thể giúp bạn tốt hơn.

0 hữu ích 0 bình luận chia sẻ
0

Nó có thể được gây ra bởi Kết xuất. Khi lật quá nhanh, bộ nhớ và CPU được sử dụng để vẽ lại "Trang" sẽ tăng lên nhanh chóng. Nếu các chế độ xem bạn đã sử dụng trong UIPageViewController dựa trên CALayer và có quá nhiều trang, việc lật quá nhanh chắc chắn sẽ làm hỏng Ứng dụng.

Một giải pháp là tùy chỉnh lớp và lưu vào bộ nhớ cache kết quả hiển thị. Chỉ hiển thị lại nội dung khi phải. Nhưng bộ nhớ đệm có thể làm tăng mức sử dụng bộ nhớ.

0 hữu ích 1 bình luận chia sẻ
0

Vì bạn không đăng bất kỳ mã nào nên rất khó để đoán chính xác vấn đề của bạn nằm ở đâu.

  1. Để buộc dỡ chế độ xem, bạn có thể ghi đè viewDidDisappear:phương thức của các lớp bộ điều khiển chế độ xem đang xuất hiện trong đó UIPageViewController.

    Mã sẽ giống như sau:

    - (void)viewDidDisappear:(BOOL)animated {
        [self didReceiveMemoryWarning];
    }
    

    Nếu bạn cũng đã overriden didReceiveMemoryWarning, đừng quên gọi [super didReceiveMemoryWarning];từ nó.

  2. Cũng có thể có một số nhầm lẫn về cách UIPageViewControllerDataSourcehoạt động của các phương pháp - bạn có thể có một số 'dây hỗn hợp ở đó'. Kiểm tra câu trả lời được chấp nhận ở đây .

0 hữu ích 0 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ ios automatic-ref-counting uipageviewcontroller , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading