在今日窗口小部件扩展中经常"无法加载"

Gab*_*iel 2 objective-c ios ios-app-extension

我正在为我的应用制作今日小部件.我的小部件包含一个包含10个单元格的UITableView.(每个单元格的高度为50pt.)功能很简单.如果我触摸单元格上的按钮,则从sqlite重新加载DB并在单元格上显示它们.除了iPhone6 +之外,它在模拟器和iPhone 4s,5,5s,6上运行良好.我确实删除了小部件并再次添加了10次,但这对我没有帮助.我确实检查过记忆和僵尸.但是在约10M下稳定并且没有泄漏.我怎样才能解决我的问题?

jee*_*yul 18

好的,伙计们,你不喜欢我之前的回答.我会重试.

考虑以下条件:

+-------------------+
| Table View        |
|+-----------------+|
|| Cell            ||
||+---------------+||
||| UILabel       |||
||+---------------+||
|+-----------------+|
+-------------------+
Run Code Online (Sandbox Code Playgroud)

首先,表的逻辑宽度是:

  • iPhone 5上的320pt(人像)
  • iPhone 6+上的414pt

内容比例因子是:

  • 0.5 for iPhone 5
  • 适用于iPhone 6+的0.33

1pt乘以1pt的实际像素为:

  • 对于iPhone 5,(1/0.5)^ 2 = 4
  • 适用于iPhone 6+(1/0.33)^ 2 = 9

那么,如果UILabel适合整个设备宽度和它的高度为44(Apple的HIG的最小可插入高度),那么,实际像素是:

  • 320*44*4 = iPhone 5的5620设备像素
  • 414*44*9 = iPhone 6+的163,944设备像素

因此,iPhone6 +需要比iPhone5大3倍的缓冲区来绘制UILabel.

但是,当窗口小部件的内存使用量超过10MB时,将发生内存错误(通过无数次实验估算).同样的限制适用于两种设备.Apple未记录此限制.

请记住,在开发iOS8扩展时,您只能使用1%的设备内存,因为它可以防止查看后台应用程序.这是支持照片编辑扩展的应用程序很少的主要原因.

无论如何,因此,需要UI的扩展程序很容易在iPhone 6+上崩溃,因为每个UI元素所需的内存量取决于大小和内容规模.

自定义绘图会导致同样的问题,因为它需要缓冲区来绘制以优化动画和渲染.iPhone6 +上缓冲区的分辨率和大小要大得多.

此外,Notification Center本身也存在漏洞(泄漏),即使只是Hello World小部件(随Xcode模板提供),每个显示和隐藏的内存消耗也在不断增加.当它最终达到10MB时,它将崩溃并将被重新加载.这就是小部件有时会闪烁的原因.如果某个小部件连续崩溃3次,iOS将永久禁用小部件并显示"无法加载".

那么,对于像这样苛刻的条件我们能解决这个问题,我为这个问题制定了一些规则.

  1. [drawRect:]除非尺寸非常小,否则不要使用实现的自定义视图.
  2. 尽可能减少视图(具有自己的内容,尤其是标签).
  3. 不要使用背景图片.

点击空白区域以选择单元格

这是与Widget相关的内存错误的常见问题,所以我也在写这个:

窗口小部件层次结构中的所有视图都倾向于具有透明背景(UIClearColor),这意味着使单元格可以进行处理非常困难.因为用户触摸空白区域时不会发生小部件的整个命中测试.(只有在至少没有透明的一个超级视图时才能应用自定义命中测试)有一些解决方案:

  1. 使UILabel的宽度适合Cell:DONT,它在iPhone6 +或更宽的高分辨率设备上消耗更多的内存.
  2. [drawRect:]在自定义单元格上实现空.不,这是轻松实现透明控制的简单解决方案,但它需要绘图缓冲区.请记住,每个设备的缓冲区大小都不同.

我可以使其无需额外内存消耗的唯一解决方案是将小部件背景颜色设置为0.01 alpha的黑色.(它使命中测试工作)

+-------------------+
| Table View        |- backgorund-color: (0, 0, 0, 0.01)
|+-----------------+|
|| Cell            ||
||+---------+      ||
||| UILabel +------++- make it small as possible as you can
||+---------+      ||
|+-----------------+|
+-------------------+
Run Code Online (Sandbox Code Playgroud)

请记住,只有背景颜色的容器视图不会占用缓冲区内存.