diff --git a/{{ cookiecutter.format }}/{{ cookiecutter.class_name }}/main.m b/{{ cookiecutter.format }}/{{ cookiecutter.class_name }}/main.m index 1acb2f7..0c43d06 100644 --- a/{{ cookiecutter.format }}/{{ cookiecutter.class_name }}/main.m +++ b/{{ cookiecutter.format }}/{{ cookiecutter.class_name }}/main.m @@ -296,10 +296,21 @@ int main(int argc, char *argv[]) { // Python does out of the box. You'll need to use // a library like Rubicon-ObjC [1], Pyobjus [2] or // PyObjC [3] if you want to run an *actual* iOS app. - // [1] http://beeware.org/rubicon + // [1] http://rubicon-objc.beeware.org/ // [2] http://pyobjus.readthedocs.org/ // [3] https://pythonhosted.org/pyobjc/ - UIApplicationMain(argc, argv, nil, @"PythonAppDelegate"); + // + // UIKit owns the native event loop. Detach Python's thread + // state so background threads and native callbacks can acquire + // the GIL while the application is idle. Restore it before + // exception handling, garbage collection, or finalization. + PyThreadState *thread_state = PyEval_SaveThread(); + @try { + UIApplicationMain(argc, argv, nil, @"PythonAppDelegate"); + } + @finally { + PyEval_RestoreThread(thread_state); + } } } @catch (NSException *exception) {