是否有可能确定内存警告的级别?

时间:2012-07-18 09:22:06

标签: iphone ios memory-management ios4

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

if(warning level == 1)
    <blah>

4 个答案:

答案 0 :(得分: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.

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

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

答案 3 :(得分: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()
}

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