Added missing autorelease pool blocks in UIKit backend code. Fixes memory leak issues, especially in SDL_video. iOS-improvements
authorAlex Szpakowski <slime73@gmail.com>
Tue, 29 Jul 2014 00:36:12 -0300
branchiOS-improvements
changeset 950618e3f94bd860
parent 9505 6fc615dfc93f
child 9507 b1e690e9c5b3
Added missing autorelease pool blocks in UIKit backend code. Fixes memory leak issues, especially in SDL_video.
src/joystick/iphoneos/SDL_sysjoystick.m
src/power/uikit/SDL_syspower.m
src/video/uikit/SDL_uikitmodes.m
src/video/uikit/SDL_uikitopengles.m
src/video/uikit/SDL_uikitview.m
src/video/uikit/SDL_uikitwindow.m
     1.1 --- a/src/joystick/iphoneos/SDL_sysjoystick.m	Tue Jul 29 00:05:48 2014 -0300
     1.2 +++ b/src/joystick/iphoneos/SDL_sysjoystick.m	Tue Jul 29 00:36:12 2014 -0300
     1.3 @@ -90,14 +90,16 @@
     1.4      joystick->nballs = 0;
     1.5      joystick->nbuttons = 0;
     1.6  
     1.7 -    if (motionManager == nil) {
     1.8 -        motionManager = [[CMMotionManager alloc] init];
     1.9 +    @autoreleasepool {
    1.10 +        if (motionManager == nil) {
    1.11 +            motionManager = [[CMMotionManager alloc] init];
    1.12 +        }
    1.13 +
    1.14 +        /* Shorter times between updates can significantly increase CPU usage. */
    1.15 +        motionManager.accelerometerUpdateInterval = 0.1;
    1.16 +        [motionManager startAccelerometerUpdates];
    1.17      }
    1.18  
    1.19 -    /* Shorter times between updates can significantly increase CPU usage. */
    1.20 -    motionManager.accelerometerUpdateInterval = 0.1;
    1.21 -    [motionManager startAccelerometerUpdates];
    1.22 -
    1.23      return 0;
    1.24  }
    1.25  
    1.26 @@ -113,12 +115,14 @@
    1.27      const SInt16 maxsint16 = 0x7FFF;
    1.28      CMAcceleration accel;
    1.29  
    1.30 -    if (!motionManager.accelerometerActive) {
    1.31 -        return;
    1.32 +    @autoreleasepool {
    1.33 +        if (!motionManager.accelerometerActive) {
    1.34 +            return;
    1.35 +        }
    1.36 +
    1.37 +        accel = motionManager.accelerometerData.acceleration;
    1.38      }
    1.39  
    1.40 -    accel = [[motionManager accelerometerData] acceleration];
    1.41 -
    1.42      /*
    1.43       Convert accelerometer data from floating point to Sint16, which is what
    1.44       the joystick system expects.
    1.45 @@ -161,7 +165,9 @@
    1.46  void
    1.47  SDL_SYS_JoystickClose(SDL_Joystick * joystick)
    1.48  {
    1.49 -    [motionManager stopAccelerometerUpdates];
    1.50 +    @autoreleasepool {
    1.51 +        [motionManager stopAccelerometerUpdates];
    1.52 +    }
    1.53      joystick->closed = 1;
    1.54  }
    1.55  
    1.56 @@ -169,9 +175,11 @@
    1.57  void
    1.58  SDL_SYS_JoystickQuit(void)
    1.59  {
    1.60 -    if (motionManager != nil) {
    1.61 -        [motionManager release];
    1.62 -        motionManager = nil;
    1.63 +    @autoreleasepool {
    1.64 +        if (motionManager != nil) {
    1.65 +            [motionManager release];
    1.66 +            motionManager = nil;
    1.67 +        }
    1.68      }
    1.69  
    1.70      numjoysticks = 0;
     2.1 --- a/src/power/uikit/SDL_syspower.m	Tue Jul 29 00:05:48 2014 -0300
     2.2 +++ b/src/power/uikit/SDL_syspower.m	Tue Jul 29 00:36:12 2014 -0300
     2.3 @@ -50,24 +50,24 @@
     2.4  SDL_bool
     2.5  SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent)
     2.6  {
     2.7 -    UIDevice *uidev = [UIDevice currentDevice];
     2.8 +    @autoreleasepool {
     2.9 +        UIDevice *uidev = [UIDevice currentDevice];
    2.10  
    2.11 -    if (!SDL_UIKitLastPowerInfoQuery) {
    2.12 -        SDL_assert([uidev isBatteryMonitoringEnabled] == NO);
    2.13 -        [uidev setBatteryMonitoringEnabled:YES];
    2.14 -    }
    2.15 +        if (!SDL_UIKitLastPowerInfoQuery) {
    2.16 +            SDL_assert(uidev.isBatteryMonitoringEnabled == NO);
    2.17 +            uidev.batteryMonitoringEnabled = YES;
    2.18 +        }
    2.19  
    2.20 -    /* UIKit_GL_SwapWindow() (etc) will check this and disable the battery
    2.21 -     *  monitoring if the app hasn't queried it in the last X seconds.
    2.22 -     *  Apparently monitoring the battery burns battery life.  :)
    2.23 -     *  Apple's docs say not to monitor the battery unless you need it.
    2.24 -     */
    2.25 -    SDL_UIKitLastPowerInfoQuery = SDL_GetTicks();
    2.26 +        /* UIKit_GL_SwapWindow() (etc) will check this and disable the battery
    2.27 +         *  monitoring if the app hasn't queried it in the last X seconds.
    2.28 +         *  Apparently monitoring the battery burns battery life.  :)
    2.29 +         *  Apple's docs say not to monitor the battery unless you need it.
    2.30 +         */
    2.31 +        SDL_UIKitLastPowerInfoQuery = SDL_GetTicks();
    2.32  
    2.33 -    *seconds = -1;   /* no API to estimate this in UIKit. */
    2.34 +        *seconds = -1;   /* no API to estimate this in UIKit. */
    2.35  
    2.36 -    switch ([uidev batteryState])
    2.37 -    {
    2.38 +        switch (uidev.batteryState) {
    2.39          case UIDeviceBatteryStateCharging:
    2.40              *state = SDL_POWERSTATE_CHARGING;
    2.41              break;
    2.42 @@ -84,11 +84,12 @@
    2.43          default:
    2.44              *state = SDL_POWERSTATE_UNKNOWN;
    2.45              break;
    2.46 +        }
    2.47 +
    2.48 +        const float level = uidev.batteryLevel;
    2.49 +        *percent = ( (level < 0.0f) ? -1 : ((int) ((level * 100) + 0.5f)) );
    2.50 +        return SDL_TRUE; /* always the definitive answer on iOS. */
    2.51      }
    2.52 -
    2.53 -    const float level = [uidev batteryLevel];
    2.54 -    *percent = ( (level < 0.0f) ? -1 : ((int) ((level * 100) + 0.5f)) );
    2.55 -    return SDL_TRUE;            /* always the definitive answer on iOS. */
    2.56  }
    2.57  
    2.58  #endif /* SDL_POWER_UIKIT */
     3.1 --- a/src/video/uikit/SDL_uikitmodes.m	Tue Jul 29 00:05:48 2014 -0300
     3.2 +++ b/src/video/uikit/SDL_uikitmodes.m	Tue Jul 29 00:36:12 2014 -0300
     3.3 @@ -159,9 +159,11 @@
     3.4  int
     3.5  UIKit_InitModes(_THIS)
     3.6  {
     3.7 -    for (UIScreen *uiscreen in [UIScreen screens]) {
     3.8 -        if (UIKit_AddDisplay(uiscreen) < 0) {
     3.9 -            return -1;
    3.10 +    @autoreleasepool {
    3.11 +        for (UIScreen *uiscreen in [UIScreen screens]) {
    3.12 +            if (UIKit_AddDisplay(uiscreen) < 0) {
    3.13 +                return -1;
    3.14 +            }
    3.15          }
    3.16      }
    3.17  
    3.18 @@ -173,26 +175,28 @@
    3.19  {
    3.20      SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
    3.21  
    3.22 -    SDL_bool isLandscape = UIKit_IsDisplayLandscape(data->uiscreen);
    3.23 -    SDL_bool addRotation = (data->uiscreen == [UIScreen mainScreen]);
    3.24 -    CGFloat scale = data->uiscreen.scale;
    3.25 +    @autoreleasepool {
    3.26 +        SDL_bool isLandscape = UIKit_IsDisplayLandscape(data->uiscreen);
    3.27 +        SDL_bool addRotation = (data->uiscreen == [UIScreen mainScreen]);
    3.28 +        CGFloat scale = data->uiscreen.scale;
    3.29  
    3.30 -    for (UIScreenMode *uimode in [data->uiscreen availableModes]) {
    3.31 -        /* The size of a UIScreenMode is in pixels, but we deal exclusively in
    3.32 -         * points (except in SDL_GL_GetDrawableSize.) */
    3.33 -        CGSize size = [uimode size];
    3.34 -        int w = (int)(size.width / scale);
    3.35 -        int h = (int)(size.height / scale);
    3.36 +        for (UIScreenMode *uimode in [data->uiscreen availableModes]) {
    3.37 +            /* The size of a UIScreenMode is in pixels, but we deal exclusively in
    3.38 +             * points (except in SDL_GL_GetDrawableSize.) */
    3.39 +            CGSize size = [uimode size];
    3.40 +            int w = (int)(size.width / scale);
    3.41 +            int h = (int)(size.height / scale);
    3.42  
    3.43 -        /* Make sure the width/height are oriented correctly */
    3.44 -        if (isLandscape != (w > h)) {
    3.45 -            int tmp = w;
    3.46 -            w = h;
    3.47 -            h = tmp;
    3.48 +            /* Make sure the width/height are oriented correctly */
    3.49 +            if (isLandscape != (w > h)) {
    3.50 +                int tmp = w;
    3.51 +                w = h;
    3.52 +                h = tmp;
    3.53 +            }
    3.54 +
    3.55 +            /* Add the native screen resolution. */
    3.56 +            UIKit_AddDisplayMode(display, w, h, uimode, addRotation);
    3.57          }
    3.58 -
    3.59 -        /* Add the native screen resolution. */
    3.60 -        UIKit_AddDisplayMode(display, w, h, uimode, addRotation);
    3.61      }
    3.62  }
    3.63  
    3.64 @@ -202,16 +206,18 @@
    3.65      SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
    3.66      SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
    3.67  
    3.68 -    [data->uiscreen setCurrentMode:modedata->uiscreenmode];
    3.69 +    @autoreleasepool {
    3.70 +        [data->uiscreen setCurrentMode:modedata->uiscreenmode];
    3.71  
    3.72 -    if (data->uiscreen == [UIScreen mainScreen]) {
    3.73 -        if (mode->w > mode->h) {
    3.74 -            if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
    3.75 -                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
    3.76 -            }
    3.77 -        } else if (mode->w < mode->h) {
    3.78 -            if (UIKit_IsDisplayLandscape(data->uiscreen)) {
    3.79 -                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
    3.80 +        if (data->uiscreen == [UIScreen mainScreen]) {
    3.81 +            if (mode->w > mode->h) {
    3.82 +                if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
    3.83 +                    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
    3.84 +                }
    3.85 +            } else if (mode->w < mode->h) {
    3.86 +                if (UIKit_IsDisplayLandscape(data->uiscreen)) {
    3.87 +                    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
    3.88 +                }
    3.89              }
    3.90          }
    3.91      }
    3.92 @@ -224,19 +230,21 @@
    3.93  {
    3.94      /* Release Objective-C objects, so higher level doesn't free() them. */
    3.95      int i, j;
    3.96 -    for (i = 0; i < _this->num_displays; i++) {
    3.97 -        SDL_VideoDisplay *display = &_this->displays[i];
    3.98 +    @autoreleasepool {
    3.99 +        for (i = 0; i < _this->num_displays; i++) {
   3.100 +            SDL_VideoDisplay *display = &_this->displays[i];
   3.101  
   3.102 -        UIKit_FreeDisplayModeData(&display->desktop_mode);
   3.103 -        for (j = 0; j < display->num_display_modes; j++) {
   3.104 -            SDL_DisplayMode *mode = &display->display_modes[j];
   3.105 -            UIKit_FreeDisplayModeData(mode);
   3.106 +            UIKit_FreeDisplayModeData(&display->desktop_mode);
   3.107 +            for (j = 0; j < display->num_display_modes; j++) {
   3.108 +                SDL_DisplayMode *mode = &display->display_modes[j];
   3.109 +                UIKit_FreeDisplayModeData(mode);
   3.110 +            }
   3.111 +
   3.112 +            SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
   3.113 +            [data->uiscreen release];
   3.114 +            SDL_free(data);
   3.115 +            display->driverdata = NULL;
   3.116          }
   3.117 -
   3.118 -        SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
   3.119 -        [data->uiscreen release];
   3.120 -        SDL_free(data);
   3.121 -        display->driverdata = NULL;
   3.122      }
   3.123  }
   3.124  
     4.1 --- a/src/video/uikit/SDL_uikitopengles.m	Tue Jul 29 00:05:48 2014 -0300
     4.2 +++ b/src/video/uikit/SDL_uikitopengles.m	Tue Jul 29 00:36:12 2014 -0300
     4.3 @@ -52,12 +52,14 @@
     4.4  int
     4.5  UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
     4.6  {
     4.7 -    if (context) {
     4.8 -        SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
     4.9 -        [data->view setCurrentContext];
    4.10 -    }
    4.11 -    else {
    4.12 -        [EAGLContext setCurrentContext: nil];
    4.13 +    @autoreleasepool {
    4.14 +        if (context) {
    4.15 +            SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
    4.16 +            [data->view setCurrentContext];
    4.17 +        }
    4.18 +        else {
    4.19 +            [EAGLContext setCurrentContext: nil];
    4.20 +        }
    4.21      }
    4.22  
    4.23      return 0;
    4.24 @@ -67,11 +69,13 @@
    4.25  {
    4.26      SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
    4.27  
    4.28 -    if (w) {
    4.29 -        *w = data->view.backingWidth;
    4.30 -    }
    4.31 -    if (h) {
    4.32 -        *h = data->view.backingHeight;
    4.33 +    @autoreleasepool {
    4.34 +        if (w) {
    4.35 +            *w = data->view.backingWidth;
    4.36 +        }
    4.37 +        if (h) {
    4.38 +            *h = data->view.backingHeight;
    4.39 +        }
    4.40      }
    4.41  }
    4.42  
    4.43 @@ -92,106 +96,112 @@
    4.44  
    4.45  void UIKit_GL_SwapWindow(_THIS, SDL_Window * window)
    4.46  {
    4.47 +    @autoreleasepool {
    4.48  #if SDL_POWER_UIKIT
    4.49 -    /* Check once a frame to see if we should turn off the battery monitor. */
    4.50 -    SDL_UIKit_UpdateBatteryMonitoring();
    4.51 +        /* Check once a frame to see if we should turn off the battery monitor. */
    4.52 +        SDL_UIKit_UpdateBatteryMonitoring();
    4.53  #endif
    4.54  
    4.55 -    SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
    4.56 +        SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
    4.57  
    4.58 -    if (nil == data->view) {
    4.59 -        return;
    4.60 +        if (nil == data->view) {
    4.61 +            return;
    4.62 +        }
    4.63 +        [data->view swapBuffers];
    4.64 +
    4.65 +        /* You need to pump events in order for the OS to make changes visible.
    4.66 +           We don't pump events here because we don't want iOS application events
    4.67 +           (low memory, terminate, etc.) to happen inside low level rendering.
    4.68 +         */
    4.69      }
    4.70 -    [data->view swapBuffers];
    4.71 -
    4.72 -    /* You need to pump events in order for the OS to make changes visible.
    4.73 -       We don't pump events here because we don't want iOS application events
    4.74 -       (low memory, terminate, etc.) to happen inside low level rendering.
    4.75 -     */
    4.76  }
    4.77  
    4.78  SDL_GLContext
    4.79  UIKit_GL_CreateContext(_THIS, SDL_Window * window)
    4.80  {
    4.81 -    SDL_uikitopenglview *view;
    4.82 -    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    4.83 -    UIWindow *uiwindow = data->uiwindow;
    4.84 -    CGRect frame = UIKit_ComputeViewFrame(window, uiwindow.screen);
    4.85 -    EAGLSharegroup *share_group = nil;
    4.86 -    CGFloat scale = 1.0;
    4.87 +    @autoreleasepool {
    4.88 +        SDL_uikitopenglview *view;
    4.89 +        SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    4.90 +        UIWindow *uiwindow = data->uiwindow;
    4.91 +        CGRect frame = UIKit_ComputeViewFrame(window, uiwindow.screen);
    4.92 +        EAGLSharegroup *share_group = nil;
    4.93 +        CGFloat scale = 1.0;
    4.94  
    4.95 -    if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
    4.96 -        /* Set the scale to the natural scale factor of the screen - the backing
    4.97 -           dimensions of the OpenGL view will match the pixel dimensions of the
    4.98 -           screen rather than the dimensions in points.
    4.99 -         */
   4.100 -        scale = uiwindow.screen.scale;
   4.101 +        if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
   4.102 +            /* Set the scale to the natural scale factor of the screen - the backing
   4.103 +               dimensions of the OpenGL view will match the pixel dimensions of the
   4.104 +               screen rather than the dimensions in points.
   4.105 +             */
   4.106 +            scale = uiwindow.screen.scale;
   4.107 +        }
   4.108 +
   4.109 +        if (_this->gl_config.share_with_current_context) {
   4.110 +            SDL_uikitopenglview *view = (SDL_uikitopenglview *) SDL_GL_GetCurrentContext();
   4.111 +            share_group = [view.context sharegroup];
   4.112 +        }
   4.113 +
   4.114 +        /* construct our view, passing in SDL's OpenGL configuration data */
   4.115 +        view = [[SDL_uikitopenglview alloc] initWithFrame: frame
   4.116 +                                                    scale: scale
   4.117 +                                            retainBacking: _this->gl_config.retained_backing
   4.118 +                                                    rBits: _this->gl_config.red_size
   4.119 +                                                    gBits: _this->gl_config.green_size
   4.120 +                                                    bBits: _this->gl_config.blue_size
   4.121 +                                                    aBits: _this->gl_config.alpha_size
   4.122 +                                                depthBits: _this->gl_config.depth_size
   4.123 +                                              stencilBits: _this->gl_config.stencil_size
   4.124 +                                                     sRGB: _this->gl_config.framebuffer_srgb_capable
   4.125 +                                             majorVersion: _this->gl_config.major_version
   4.126 +                                               shareGroup: share_group];
   4.127 +        if (!view) {
   4.128 +            return NULL;
   4.129 +        }
   4.130 +
   4.131 +        data->view = view;
   4.132 +        view->viewcontroller = data->viewcontroller;
   4.133 +        if (view->viewcontroller != nil) {
   4.134 +            [view->viewcontroller setView:view];
   4.135 +            [view->viewcontroller retain];
   4.136 +        }
   4.137 +        [uiwindow addSubview: view];
   4.138 +
   4.139 +        /* The view controller needs to be the root in order to control rotation on iOS 6.0 */
   4.140 +        if (uiwindow.rootViewController == nil) {
   4.141 +            uiwindow.rootViewController = view->viewcontroller;
   4.142 +        }
   4.143 +
   4.144 +        if (UIKit_GL_MakeCurrent(_this, window, view) < 0) {
   4.145 +            UIKit_GL_DeleteContext(_this, view);
   4.146 +            return NULL;
   4.147 +        }
   4.148 +
   4.149 +        /* Make this window the current mouse focus for touch input */
   4.150 +        if (uiwindow.screen == [UIScreen mainScreen]) {
   4.151 +            SDL_SetMouseFocus(window);
   4.152 +            SDL_SetKeyboardFocus(window);
   4.153 +        }
   4.154 +
   4.155 +        return view;
   4.156      }
   4.157 -
   4.158 -    if (_this->gl_config.share_with_current_context) {
   4.159 -        SDL_uikitopenglview *view = (SDL_uikitopenglview *) SDL_GL_GetCurrentContext();
   4.160 -        share_group = [view.context sharegroup];
   4.161 -    }
   4.162 -
   4.163 -    /* construct our view, passing in SDL's OpenGL configuration data */
   4.164 -    view = [[SDL_uikitopenglview alloc] initWithFrame: frame
   4.165 -                                                scale: scale
   4.166 -                                        retainBacking: _this->gl_config.retained_backing
   4.167 -                                                rBits: _this->gl_config.red_size
   4.168 -                                                gBits: _this->gl_config.green_size
   4.169 -                                                bBits: _this->gl_config.blue_size
   4.170 -                                                aBits: _this->gl_config.alpha_size
   4.171 -                                            depthBits: _this->gl_config.depth_size
   4.172 -                                          stencilBits: _this->gl_config.stencil_size
   4.173 -                                                 sRGB: _this->gl_config.framebuffer_srgb_capable
   4.174 -                                         majorVersion: _this->gl_config.major_version
   4.175 -                                           shareGroup: share_group];
   4.176 -    if (!view) {
   4.177 -        return NULL;
   4.178 -    }
   4.179 -
   4.180 -    data->view = view;
   4.181 -    view->viewcontroller = data->viewcontroller;
   4.182 -    if (view->viewcontroller != nil) {
   4.183 -        [view->viewcontroller setView:view];
   4.184 -        [view->viewcontroller retain];
   4.185 -    }
   4.186 -    [uiwindow addSubview: view];
   4.187 -
   4.188 -    /* The view controller needs to be the root in order to control rotation on iOS 6.0 */
   4.189 -    if (uiwindow.rootViewController == nil) {
   4.190 -        uiwindow.rootViewController = view->viewcontroller;
   4.191 -    }
   4.192 -
   4.193 -    if (UIKit_GL_MakeCurrent(_this, window, view) < 0) {
   4.194 -        UIKit_GL_DeleteContext(_this, view);
   4.195 -        return NULL;
   4.196 -    }
   4.197 -
   4.198 -    /* Make this window the current mouse focus for touch input */
   4.199 -    if (uiwindow.screen == [UIScreen mainScreen]) {
   4.200 -        SDL_SetMouseFocus(window);
   4.201 -        SDL_SetKeyboardFocus(window);
   4.202 -    }
   4.203 -
   4.204 -    return view;
   4.205  }
   4.206  
   4.207  void
   4.208  UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
   4.209  {
   4.210 -    /* the delegate has retained the view, this will release him */
   4.211 -    SDL_uikitopenglview *view = (SDL_uikitopenglview *)context;
   4.212 -    if (view->viewcontroller) {
   4.213 -        UIWindow *uiwindow = (UIWindow *)view.superview;
   4.214 -        if (uiwindow.rootViewController == view->viewcontroller) {
   4.215 -            uiwindow.rootViewController = nil;
   4.216 +    @autoreleasepool {
   4.217 +        /* the delegate has retained the view, this will release him */
   4.218 +        SDL_uikitopenglview *view = (SDL_uikitopenglview *)context;
   4.219 +        if (view->viewcontroller) {
   4.220 +            UIWindow *uiwindow = (UIWindow *)view.superview;
   4.221 +            if (uiwindow.rootViewController == view->viewcontroller) {
   4.222 +                uiwindow.rootViewController = nil;
   4.223 +            }
   4.224 +            [view->viewcontroller setView:nil];
   4.225 +            [view->viewcontroller release];
   4.226          }
   4.227 -        [view->viewcontroller setView:nil];
   4.228 -        [view->viewcontroller release];
   4.229 +        [view removeFromSuperview];
   4.230 +        [view release];
   4.231      }
   4.232 -    [view removeFromSuperview];
   4.233 -    [view release];
   4.234  }
   4.235  
   4.236  #endif /* SDL_VIDEO_DRIVER_UIKIT */
     5.1 --- a/src/video/uikit/SDL_uikitview.m	Tue Jul 29 00:05:48 2014 -0300
     5.2 +++ b/src/video/uikit/SDL_uikitview.m	Tue Jul 29 00:36:12 2014 -0300
     5.3 @@ -318,28 +318,34 @@
     5.4  
     5.5  void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
     5.6  {
     5.7 -    SDL_uikitview *view = getWindowView(window);
     5.8 -    if (view != nil) {
     5.9 -        [view showKeyboard];
    5.10 +    @autoreleasepool {
    5.11 +        SDL_uikitview *view = getWindowView(window);
    5.12 +        if (view != nil) {
    5.13 +            [view showKeyboard];
    5.14 +        }
    5.15      }
    5.16  }
    5.17  
    5.18  void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
    5.19  {
    5.20 -    SDL_uikitview *view = getWindowView(window);
    5.21 -    if (view != nil) {
    5.22 -        [view hideKeyboard];
    5.23 +    @autoreleasepool {
    5.24 +        SDL_uikitview *view = getWindowView(window);
    5.25 +        if (view != nil) {
    5.26 +            [view hideKeyboard];
    5.27 +        }
    5.28      }
    5.29  }
    5.30  
    5.31  SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
    5.32  {
    5.33 -    SDL_uikitview *view = getWindowView(window);
    5.34 -    if (view == nil) {
    5.35 -        return 0;
    5.36 +    @autoreleasepool {
    5.37 +        SDL_uikitview *view = getWindowView(window);
    5.38 +        if (view == nil) {
    5.39 +            return 0;
    5.40 +        }
    5.41 +
    5.42 +        return view.isKeyboardVisible;
    5.43      }
    5.44 -
    5.45 -    return view.isKeyboardVisible;
    5.46  }
    5.47  
    5.48  
    5.49 @@ -423,13 +429,15 @@
    5.50          SDL_InvalidParamError("rect");
    5.51          return;
    5.52      }
    5.53 -    
    5.54 -    SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
    5.55 -    if (view == nil) {
    5.56 -        return ;
    5.57 +
    5.58 +    @autoreleasepool {
    5.59 +        SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
    5.60 +        if (view == nil) {
    5.61 +            return;
    5.62 +        }
    5.63 +
    5.64 +        view.textInputRect = *rect;
    5.65      }
    5.66 -
    5.67 -    view.textInputRect = *rect;
    5.68  }
    5.69  
    5.70  
     6.1 --- a/src/video/uikit/SDL_uikitwindow.m	Tue Jul 29 00:05:48 2014 -0300
     6.2 +++ b/src/video/uikit/SDL_uikitwindow.m	Tue Jul 29 00:36:12 2014 -0300
     6.3 @@ -132,84 +132,86 @@
     6.4  int
     6.5  UIKit_CreateWindow(_THIS, SDL_Window *window)
     6.6  {
     6.7 -    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
     6.8 -    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
     6.9 -    const BOOL external = ([UIScreen mainScreen] != data->uiscreen);
    6.10 -    const CGSize origsize = [[data->uiscreen currentMode] size];
    6.11 +    @autoreleasepool {
    6.12 +        SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
    6.13 +        SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
    6.14 +        const BOOL external = ([UIScreen mainScreen] != data->uiscreen);
    6.15 +        const CGSize origsize = [[data->uiscreen currentMode] size];
    6.16  
    6.17 -    /* SDL currently puts this window at the start of display's linked list. We rely on this. */
    6.18 -    SDL_assert(_this->windows == window);
    6.19 +        /* SDL currently puts this window at the start of display's linked list. We rely on this. */
    6.20 +        SDL_assert(_this->windows == window);
    6.21  
    6.22 -    /* We currently only handle a single window per display on iOS */
    6.23 -    if (window->next != NULL) {
    6.24 -        return SDL_SetError("Only one window allowed per display.");
    6.25 -    }
    6.26 -
    6.27 -    /* If monitor has a resolution of 0x0 (hasn't been explicitly set by the
    6.28 -     * user, so it's in standby), try to force the display to a resolution
    6.29 -     * that most closely matches the desired window size.
    6.30 -     */
    6.31 -    if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
    6.32 -        if (display->num_display_modes == 0) {
    6.33 -            _this->GetDisplayModes(_this, display);
    6.34 +        /* We currently only handle a single window per display on iOS */
    6.35 +        if (window->next != NULL) {
    6.36 +            return SDL_SetError("Only one window allowed per display.");
    6.37          }
    6.38  
    6.39 -        int i;
    6.40 -        const SDL_DisplayMode *bestmode = NULL;
    6.41 -        for (i = display->num_display_modes; i >= 0; i--) {
    6.42 -            const SDL_DisplayMode *mode = &display->display_modes[i];
    6.43 -            if ((mode->w >= window->w) && (mode->h >= window->h))
    6.44 -                bestmode = mode;
    6.45 +        /* If monitor has a resolution of 0x0 (hasn't been explicitly set by the
    6.46 +         * user, so it's in standby), try to force the display to a resolution
    6.47 +         * that most closely matches the desired window size.
    6.48 +         */
    6.49 +        if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
    6.50 +            if (display->num_display_modes == 0) {
    6.51 +                _this->GetDisplayModes(_this, display);
    6.52 +            }
    6.53 +
    6.54 +            int i;
    6.55 +            const SDL_DisplayMode *bestmode = NULL;
    6.56 +            for (i = display->num_display_modes; i >= 0; i--) {
    6.57 +                const SDL_DisplayMode *mode = &display->display_modes[i];
    6.58 +                if ((mode->w >= window->w) && (mode->h >= window->h))
    6.59 +                    bestmode = mode;
    6.60 +            }
    6.61 +
    6.62 +            if (bestmode) {
    6.63 +                SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)bestmode->driverdata;
    6.64 +                [data->uiscreen setCurrentMode:modedata->uiscreenmode];
    6.65 +
    6.66 +                /* desktop_mode doesn't change here (the higher level will
    6.67 +                 * use it to set all the screens back to their defaults
    6.68 +                 * upon window destruction, SDL_Quit(), etc.
    6.69 +                 */
    6.70 +                display->current_mode = *bestmode;
    6.71 +            }
    6.72          }
    6.73  
    6.74 -        if (bestmode) {
    6.75 -            SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)bestmode->driverdata;
    6.76 -            [data->uiscreen setCurrentMode:modedata->uiscreenmode];
    6.77 -
    6.78 -            /* desktop_mode doesn't change here (the higher level will
    6.79 -             * use it to set all the screens back to their defaults
    6.80 -             * upon window destruction, SDL_Quit(), etc.
    6.81 -             */
    6.82 -            display->current_mode = *bestmode;
    6.83 -        }
    6.84 -    }
    6.85 -
    6.86 -    if (data->uiscreen == [UIScreen mainScreen]) {
    6.87 -        if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
    6.88 -            [UIApplication sharedApplication].statusBarHidden = YES;
    6.89 -        } else {
    6.90 -            [UIApplication sharedApplication].statusBarHidden = NO;
    6.91 -        }
    6.92 -    }
    6.93 -
    6.94 -    if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
    6.95 -        if (window->w > window->h) {
    6.96 -            if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
    6.97 -                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
    6.98 -            }
    6.99 -        } else if (window->w < window->h) {
   6.100 -            if (UIKit_IsDisplayLandscape(data->uiscreen)) {
   6.101 -                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
   6.102 +        if (data->uiscreen == [UIScreen mainScreen]) {
   6.103 +            if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
   6.104 +                [UIApplication sharedApplication].statusBarHidden = YES;
   6.105 +            } else {
   6.106 +                [UIApplication sharedApplication].statusBarHidden = NO;
   6.107              }
   6.108          }
   6.109 -    }
   6.110  
   6.111 -    /* ignore the size user requested, and make a fullscreen window */
   6.112 -    /* !!! FIXME: can we have a smaller view? */
   6.113 -    SDL_uikitwindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data->uiscreen.bounds];
   6.114 +        if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
   6.115 +            if (window->w > window->h) {
   6.116 +                if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
   6.117 +                    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
   6.118 +                }
   6.119 +            } else if (window->w < window->h) {
   6.120 +                if (UIKit_IsDisplayLandscape(data->uiscreen)) {
   6.121 +                    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
   6.122 +                }
   6.123 +            }
   6.124 +        }
   6.125  
   6.126 -    /* put the window on an external display if appropriate. This implicitly
   6.127 -     * does [uiwindow setframe:[uiscreen bounds]], so don't do it on the
   6.128 -     * main display, where we land by default, as that would eat the
   6.129 -     * status bar real estate.
   6.130 -     */
   6.131 -    if (external) {
   6.132 -        [uiwindow setScreen:data->uiscreen];
   6.133 -    }
   6.134 +        /* ignore the size user requested, and make a fullscreen window */
   6.135 +        /* !!! FIXME: can we have a smaller view? */
   6.136 +        SDL_uikitwindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data->uiscreen.bounds];
   6.137  
   6.138 -    if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
   6.139 -        [uiwindow release];
   6.140 -        return -1;
   6.141 +        /* put the window on an external display if appropriate. This implicitly
   6.142 +         * does [uiwindow setframe:[uiscreen bounds]], so don't do it on the
   6.143 +         * main display, where we land by default, as that would eat the
   6.144 +         * status bar real estate.
   6.145 +         */
   6.146 +        if (external) {
   6.147 +            [uiwindow setScreen:data->uiscreen];
   6.148 +        }
   6.149 +
   6.150 +        if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
   6.151 +            [uiwindow release];
   6.152 +            return -1;
   6.153 +        }
   6.154      }
   6.155  
   6.156      return 1;
   6.157 @@ -218,17 +220,21 @@
   6.158  void
   6.159  UIKit_ShowWindow(_THIS, SDL_Window * window)
   6.160  {
   6.161 -    UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
   6.162 +    @autoreleasepool {
   6.163 +        UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
   6.164  
   6.165 -    [uiwindow makeKeyAndVisible];
   6.166 +        [uiwindow makeKeyAndVisible];
   6.167 +    }
   6.168  }
   6.169  
   6.170  void
   6.171  UIKit_HideWindow(_THIS, SDL_Window * window)
   6.172  {
   6.173 -    UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
   6.174 +    @autoreleasepool {
   6.175 +        UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
   6.176  
   6.177 -    uiwindow.hidden = YES;
   6.178 +        uiwindow.hidden = YES;
   6.179 +    }
   6.180  }
   6.181  
   6.182  void
   6.183 @@ -286,13 +292,17 @@
   6.184  void
   6.185  UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
   6.186  {
   6.187 -    UIKit_UpdateWindowBorder(_this, window);
   6.188 +    @autoreleasepool {
   6.189 +        UIKit_UpdateWindowBorder(_this, window);
   6.190 +    }
   6.191  }
   6.192  
   6.193  void
   6.194  UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
   6.195  {
   6.196 -    UIKit_UpdateWindowBorder(_this, window);
   6.197 +    @autoreleasepool {
   6.198 +        UIKit_UpdateWindowBorder(_this, window);
   6.199 +    }
   6.200  }
   6.201  
   6.202  void
   6.203 @@ -300,27 +310,32 @@
   6.204  {
   6.205      SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
   6.206  
   6.207 -    if (data) {
   6.208 -        [data->viewcontroller release];
   6.209 -        [data->uiwindow release];
   6.210 -        SDL_free(data);
   6.211 +    @autoreleasepool {
   6.212 +        if (data) {
   6.213 +            [data->viewcontroller release];
   6.214 +            [data->uiwindow release];
   6.215 +            SDL_free(data);
   6.216 +        }
   6.217      }
   6.218 +
   6.219      window->driverdata = NULL;
   6.220  }
   6.221  
   6.222  SDL_bool
   6.223  UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
   6.224  {
   6.225 -    UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
   6.226 +    @autoreleasepool {
   6.227 +        UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
   6.228  
   6.229 -    if (info->version.major <= SDL_MAJOR_VERSION) {
   6.230 -        info->subsystem = SDL_SYSWM_UIKIT;
   6.231 -        info->info.uikit.window = uiwindow;
   6.232 -        return SDL_TRUE;
   6.233 -    } else {
   6.234 -        SDL_SetError("Application not compiled with SDL %d.%d\n",
   6.235 -                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
   6.236 -        return SDL_FALSE;
   6.237 +        if (info->version.major <= SDL_MAJOR_VERSION) {
   6.238 +            info->subsystem = SDL_SYSWM_UIKIT;
   6.239 +            info->info.uikit.window = uiwindow;
   6.240 +            return SDL_TRUE;
   6.241 +        } else {
   6.242 +            SDL_SetError("Application not compiled with SDL %d.%d\n",
   6.243 +                         SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
   6.244 +            return SDL_FALSE;
   6.245 +        }
   6.246      }
   6.247  }
   6.248  
   6.249 @@ -333,7 +348,10 @@
   6.250          return SDL_SetError("Invalid window or view not set");
   6.251      }
   6.252  
   6.253 -    [data->view setAnimationCallback:interval callback:callback callbackParam:callbackParam];
   6.254 +    @autoreleasepool {
   6.255 +        [data->view setAnimationCallback:interval callback:callback callbackParam:callbackParam];
   6.256 +    }
   6.257 +
   6.258      return 0;
   6.259  }
   6.260