Розробка iOS: Як я можу викликати попередження про низьку пам’ять на пристрої?


93

Я хотів би добре протестувати свої функції програми в умовах недостатньої пам’яті, але це складно перевірити. Як я можу викликати попередження про низький обсяг пам’яті, які викликають метод didReceiveMemoryWarning у моїх поданнях, коли програма працює на пристрої, а не на симуляторі? Або як я можу протестувати свій додаток за цих можливих умов?

Причиною того, що я не можу використовувати симулятор, є те, що мій додаток використовує Game Center, а запрошення не працюють на симуляторі.

Відповіді:


9

Щоб протестувати на пристрої, просто додайте код, який періодично виділяє великі шматки пам'яті, не звільняючи її (тобто спеціально витікає). Ви можете зробити це в окремому ланцюжку, або у відповідь на таймер, або використовуючи будь-який механізм, який найкраще дозволяє протестувати та спостерігати за поведінкою вашої програми.

Ви також можете створити окремий додаток, який робить щось подібне і призначений для роботи у фоновому режимі, якщо ви хочете легко використовувати це повторно та / або тестувати з кількома програмами.


7
не дуже практично. рішення для виклику приватного методу для тестування є кращим
Дайдж-Джан

5
Невдале рішення, якщо ви хочете розглянути реальний сценарій. Ви скалічуєте програму через витік, не через тиск пам'яті. Це погано, оскільки те, що ви хочете зробити, - це перевірити, як додаток реагує у стані високого тиску пам’яті. З мінусів важче зрозуміти, в чому проблема справжнього витоку чи підробленого, який ви ввели. Приватний метод краще використовувати для тестування, як зазначено нижче.
fzaziz

2
Цю відповідь не слід голосувати проти, оскільки другий абзац насправді є тим, що Apple каже робити, якщо ви хочете перевірити поведінку свого додатка, коли пам’ять дійсно вичерпується.
matt

1
Відповідь буде покращено за допомогою блоку коду для виконання цього розподілу!
pkamb

Хоча для налаштування потрібно більше роботи, це більш реалістичний тест, ніж виклик приватного методу. Коли справді виникає критичний тиск пам’яті, чи зможе ваш додаток виконувати дії, які ви йому наказали? І ці дії полегшать ситуацію або погіршать ситуацію та змусять iOS припинити її? Крім того, приватний метод не працює для тестування DISPATCH_SOURCE_TYPE_MEMORYPRESSURE.
jk7

278

Ви можете викликати приватний метод :

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

Просто пам’ятайте використовувати його лише для налагодження, інакше ваш додаток буде відхилено.


6
Здається, цей код точно імітує попередження про пам’ять на пристрої. Дякую, Енцо!
Вільям Денніс,

28
Замість того, щоб використовувати це в коді, виконайте його в налагоджувачі. Просто натисніть паузу та введітьpo [[UIApplication sharedApplication]performSelector:@selector(_performMemoryWarning)]
orkoden

17
Замість того, щоб використовувати po, використовуйте expr, тобтоexpr (void)[[UIApplication sharedApplication] performSelector:@selector(_performMemoryWarning)];
Енді

11
У налагоджувачі не потрібно використовувати обхідний шлях через відсутність заголовка:expr (void)[[UIApplication sharedApplication] _performMemoryWarning]
OrangeDog

3
Для тих, хто хоче зробити це за допомогою Swift: введіть expr UIApplication.sharedApplication().performSelector("_performMemoryWarning")замість звичайного#selector
funct7

29

Simulate Memory WarningПункт меню iOS Simulator дозволяє імітувати попередження про пам'ять.


Єдиний спосіб перевірити це на пристрої - це насправді змусити його, тобто, використовуючи програму протягом тривалого періоду часу або інтенсивних зображень, або те, що у вас, буде змінювати додаток залежно від додатка. Пропозицією може бути використання старішого пристрою (можливо, 3g?) Замість iPhone 4, щоб швидше дістатися до попередження.
Джессі Нагер

Дякую, Джессі, я думаю, що я просто додам кілька хаків у свій додаток для імітації запрошень, щоб я міг запустити його в симуляторі і викликати попередження про пам'ять таким чином.
BeachRunnerFred

10
Питання було про моделювання на пристрої.
KPM

20

Використовуючи Інструменти, використовуйте пункт меню: Інструмент -> Імітувати попередження про пам’ять.

Щоб використовувати Інструменти у своєму додатку з Xcode, використовуйте пункт меню Продукт -> Профіль.


Це ще краще.
Zappel

@OrangeDog Що відбувається?
ThomasW

2
Ну нічого. Коли я використовую відповіді Enzo, подання повинні перезавантажуватися, коли я повертаюся до них, не так, використовуючи цей метод.
OrangeDog

12

Я переписав відповідь Енцо Тран у Swift:

UIControl().sendAction(Selector(("_performMemoryWarning")), to: UIApplication.shared, for: nil)

Дякую! Xcode попереджає про "відсутність методу, оголошеного за допомогою селектора Objective-C", але це тим не менше працює.
людина1

10

Якщо хтось з якихось причин намагається зробити це в Swift 4 - ось як виділити 1,2 ГБ оперативної пам'яті.

let d = Data.init(repeating: 100, count: 1200000000)
  • Це корисно, щоб викликати попереджувальне попередження в інших програмах

Чи буде щось подібне затьмарювати фактичну інформацію про пам’ять, яку я намагаюся переглянути в Інструментах? Хоча я бачу, що не існує належного способу зробити це на фізичному пристрої, якщо я маю на меті побачити, що займає мою пам’ять у моїй програмі, здається, що це зіпсує всі дані, і я ні довше мають відносну відповідь. Я все одно побачу, що забирає більше , але не справжні пропорції.
Jake T.

це негайно падає
Деніел Спрінгер

8

Перетворено @ChikabuZ на швидкий 3:

UIControl().sendAction(Selector(("_performMemoryWarning")), to: UIApplication.shared, for: nil)

7

Є команда меню, яка її буде викликати.

Hardware > Simulate Memory Warning з тренажера.


8
Питання було про моделювання на пристрої.
KPM

2
У Xcode 10 це тепер у розділі Налагодження> Імітувати попередження про пам'ять.
Себбо,

4

Якщо хтось з якихось причин намагається зробити це в Swift 3 - ось як розподілити 1,2 ГБ оперативної пам'яті.

   for i in 0...1200 {
      var p: [UnsafeMutableRawPointer] = []
      var allocatedMB = 0
      p.append(malloc(1048576))
      memset(p[allocatedMB], 0, 1048576);
      allocatedMB += 1;
   }

3
нехай d = Data.init (повторюється: 100, рахує:
1200000000

2
@Adobels ви повинні опублікувати це як відповідь :)
Коен.

1

Свіфт 4:

UIApplication.shared.perform (Селектор (("_ performMemoryWarning")))

Може виконати вищевказане у відповідь на подію / сповіщення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.