App used 98% CPU under IOS 11

I have an App that works fine with IOS 10.3. However, when the same App compiled and ran under IOS 11, the Main thread took up 98% of the CPU. Timing profile showed that it is [UITextSelectionView caretBlinkTimerFired]. Half of the cycle spent in showCaret and the other half in hideCaret.


Here is the tree:


Main Thread

start

0x100b2fcde

UIApplicationMain

GSEventRunModal

CFRunLoopRunSpecific

_CFRunLoopRun

_CFRunLoopDoTimer

_DFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION_

_NFFireTimer

-[UITextSelectionView caretBlinkTimerFired:]

48% - [UITextSelectionView showCaret:]

48% -[UITextSelectView hideCaret:]


What should I do to figure out where the problem is?

I don't even need to run the app on real device, the problem can be demonstrated with IOS 10.3 simulator and IOS 11 simulator.


Any help would be greatly appreciated.

By commenting out different section of code in viewDidLoad of my main View Controller, I narrow the problem down to the following statement


[self.view addSubview:mixerView.view];


If this statement is in, the processor usage stays close to 100%. If I comment this out, the processor usage is close to nothing. mixerView has a very large table with hundreds of UITextFields. Seems like all these UITextFields were all trying to blink their caret even though this subView was not even visible yet. The rest of the problem also didn't talk to the mixerView controller.


Interesting thing is, if I click a button on my main view to bring up an Alert with a UITextField for text entry (took a long time to popup), the capture of the focus by this text field immediately brings the processor usage down to nothing. The program from that point on behaved normally.

I have exactly the same problem but I still can't figure out how to fix it. Since it seems an iOS 11 bug I think it's also quite impossible for us to fix.

For me it happens with a table with two textfields for each row. Everytime I allocate them, the CPU usage raise 4-5% and never get down till the point that the device is unusable.

Also getting the same problem on a view with dozens of text fields (150% CPU usage). iOS11 only.


Really bad bug.


Apple please fix ...

We can only fix bugs that we know about, and the official way of letting us know about a bug is to file a bug report at bugreport.apple.com. The most effective way of doing this is to attach a sample project that exhibits the behavior so that we can reproduce it here. You should never assume that we know about a bug and you should always file a bug report. It's certainly possible that we already have reports about it, but all too often there's something unique about your setup or configuration that has prevented us from seeing the issue.


So please get bugs filed and post your bug numbers here.

I did file a report on this at the same time as posting on forum (number 35070942). Hasn't had any comments by Apple yet as of writing this.


It seems there is a temporary workaround by subclassing and overriding this:


- (CGRect)caretRectForPosition:(UITextPosition *)position {
     return CGRectZero; 
}


But it doesn't seem to work in all cases. Still investigating ...

I tried that too, but in my case didn't work 😟

File report: 35121759

Didn't work in my case too.

This works:

If your text is nil or text length == 0 -> add a blank character

If your text is nil or text length == 0 -> add a blank character


Confirmed: this fixed it for me. Making default @" " instead of @""

Yeah, it works. Still it's a manual patch that sometimes you can't use...

Didn't have time to check back here until now.


I have a 144x8 table. Fortunately I could select 144 at a time and set the default text to a single blank character in the Storyboard.

That fixed the problem.


Thank you very much for the work around.

This works, but by doing this, the underlying UITextField will not display the placeholder text. This is a particularly nasty iOS bug that is killing my app. Apple needs to fix this ASAP.

I have a workaround for this iOS bug that works. The rule you have to have is that before you add a UITextField or UITextView as a subview to a view, you must first check to see if the text value of the item being added is not nil or the empty string. If it is, you must then set it to a single space string (" ") before adding it to the view heirachy. Once you do this, in the next run loop, you can then set the text value to the empty string again. I use GCD to do a delayed procedure to do this.

App used 98% CPU under IOS 11
 
 
Q