I'm making a Today widget for my app. My widget contains a UITableView with 10 cells. (Each cell's height is 50pt.) Function is simple. If I touch up a button on cell, reload DB from sqlite and show them on cells. It works very well on simulator and iPhone 4s, 5, 5s, 6 except only iPhone6+. I did remove widget and add again over 10 times, but It's not helpful for me. I did check memory and zombie. but that is stabilized under ~10M and no leaks. How can I solve my problem?
Okay, guys, You don't like my previous answer. I will retry.
Consider below condition:
+-------------------+
| Table View |
|+-----------------+|
|| Cell ||
||+---------------+||
||| UILabel |||
||+---------------+||
|+-----------------+|
+-------------------+
At first the logical width of the table is:
And the content scale factors are:
Actual pixels for 1pt by 1pt are:
So what if a UILabel
fit to entire device width and it's height is 44(minimum tappable height by Apple's HIG), therefore, actual pixels are:
As a result, iPhone6+ requires 3 more times larger buffer than to iPhone5 to draw UILabel.
However, The memory error will be occurred when memory usage of the widget exceed 10MB(Estimated by countless experiments). This same limitation is applies to both device. This limitation is not documented by Apple.
Please remember, you can use only 1% of device memory when you developing iOS8 extensions due to prevent killing background apps. This is the main reason for that there are few apps that support photo editing extension.
Anyway, As a result, Extensions that requires UI are crash easily on iPhone 6+ since the required amount of the memory for each UI element depend on size and content scale.
Custom drawing causes same problem since it requires buffer to draw to optimize animations and rendering. And the resolution and size of the buffer is much bigger on iPhone6+.
In addition, there are bugs(leak) for Notification Center itself, even just Hello World widget(comes with Xcode template) keeps growing memory consumption per each showing and hiding. When eventually it reaches 10MB, it will crash and will be reloaded. It is the reason for that widgets are sometimes flashing. What if some widget crashes 3 times continuously, iOS permanently disable the widget and shows "Unable to Load".
So, what can we do about this problem with such harsh conditions like this, I made some rules for this problem.
[drawRect:]
except when it is extremely small size.This is pretty common problem for Widget that is related memory error, So I'm writing about this also:
All views in widget hierarchy tend to have transparent background(UIClearColor
), it means that making cell tappable is pretty hard. Because entire hit testing for widget will not be occurred when user touch empty area. (custom hit testing only can be applied when there is not transparent one superview at least) There are some solutions for it:
[drawRect:]
on custom cell. DONT, This is pretty easy solution for tapping transparent control, however it requires drawing buffer. Remember the buffer size will be different for each devices.The only solution that I could make it works without additional memory consumption is that the setting widget background color as the black color with 0.01 alpha. (It makes hit-testing works)
+-------------------+
| Table View |- backgorund-color: (0, 0, 0, 0.01)
|+-----------------+|
|| Cell ||
||+---------+ ||
||| UILabel +------++- make it small as possible as you can
||+---------+ ||
|+-----------------+|
+-------------------+
Remember that the container view with just background color will not occupy buffer memory.