0

我在 didReceiveMemoryWarning 中收到内存警告。我知道内存警告有不同的级别,例如 level-1、level-2。有没有办法确定警告级别?例子:

if(warning level == 1)
    <blah>
4

4 回答 4

2

希望这可以帮助!!!

有 4 个级别的警告(0 到 3)。这些是从内核内存观察器设置的,可以通过不那么公开的函数 OSMemoryNotificationCurrentLevel() 获得。

typedef enum {
    OSMemoryNotificationLevelAny      = -1,
    OSMemoryNotificationLevelNormal   =  0,
    OSMemoryNotificationLevelWarning  =  1,
    OSMemoryNotificationLevelUrgent   =  2,
    OSMemoryNotificationLevelCritical =  3
} OSMemoryNotificationLevel;

没有记录级别是如何触发的。SpringBoard 配置为在每个内存级别执行以下操作:

Warning (not-normal) — Relaunch, or delay auto relaunch of nonessential background apps e.g. Mail.
Urgent — Quit all background apps, e.g. Safari and iPod.
Critical and beyond — The kernel will take over, probably killing SpringBoard or even reboot.
于 2012-07-18T10:41:06.993 回答
1

我知道没有办法(除了私有/未记录的 API)知道内存级别警告。所以你不应该使用它。

查看问题以查看未记录的 API 以获取内存警告级别。

于 2012-07-18T10:23:50.500 回答
0

我的第一个建议是研究文档中的内存警告通知(例如,userInfo如果存在,它的字典的内容是什么)。我不知道它是否提供了任何细节。

但最终,您不应该推测内存警告的级别,只需假设最坏的情况并尽可能多地释放未使用的数据。

于 2012-07-18T09:25:36.833 回答
0

没有(公共的、有效的)方法可以从客户设备上的系统中获取当前的内存压力水平。然而,有一种方法可以使用Dispatch Source API获得内存压力变化的通知。

内存压力调度源可用于通知应用程序内存压力的变化。这可以比 UIKit 提供的通知更细粒度,并且包括在内存压力恢复正常时通知的能力。

例如:

目标-C:

dispatch_source_t   memorySource    = NULL;

memorySource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0L, (DISPATCH_MEMORYPRESSURE_NORMAL | DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL), [self privateQueue]);
if (memorySource != NULL) {
    dispatch_block_t eventHandler = dispatch_block_create(DISPATCH_BLOCK_ASSIGN_CURRENT, ^{
        if (dispatch_source_testcancel(memorySource) == 0 ){
            dispatch_source_memorypressure_flags_t  memoryPressure    = dispatch_source_get_data(memorySource);

            [self didReceiveMemoryPressure:memoryPressure];
        }
    });

   dispatch_source_set_event_handler(memorySource, eventHandler);
   dispatch_source_set_registration_handler(memorySource, eventHandler);
   [self setSource:memorySource];
   dispatch_activate([self source]);
}

斯威夫特 4:

if let source:DispatchSourceMemoryPressure = DispatchSource.makeMemoryPressureSource(eventMask: .all, queue:self.privateQueue) as? DispatchSource {

    let eventHandler: DispatchSourceProtocol.DispatchSourceHandler = {
        let event:DispatchSource.MemoryPressureEvent = source.data
        if source.isCancelled == false {
            self.didReceive(memoryPressureEvent: event)
        }
    }

    source.setEventHandler(handler:eventHandler)
    source.setRegistrationHandler(handler:eventHandler)
    self.source = source
    self.source?.activate()
}

请注意,事件处理程序也被用作“注册处理程序”。这将导致事件处理程序在调度源被激活时触发,有效地告诉应用程序当源被激活时“当前”值是什么。

于 2018-04-09T21:13:03.277 回答