Updated the iOS backend code to use Objective-C's automatic reference counting (ARC). iOS-improvements
authorAlex Szpakowski <slime73@gmail.com>
Wed, 06 Aug 2014 03:24:16 -0300
branchiOS-improvements
changeset 9510 e19faa3b5d88
parent 9509 350f38eb3d0f
child 9511 f08e88fe9de5
Updated the iOS backend code to use Objective-C's automatic reference counting (ARC).
Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj
include/SDL_syswm.h
src/file/cocoa/SDL_rwopsbundlesupport.m
src/joystick/iphoneos/SDL_sysjoystick.m
src/video/uikit/SDL_uikitappdelegate.m
src/video/uikit/SDL_uikitmessagebox.m
src/video/uikit/SDL_uikitmodes.h
src/video/uikit/SDL_uikitmodes.m
src/video/uikit/SDL_uikitopengles.m
src/video/uikit/SDL_uikitopenglview.h
src/video/uikit/SDL_uikitopenglview.m
src/video/uikit/SDL_uikitview.h
src/video/uikit/SDL_uikitview.m
src/video/uikit/SDL_uikitwindow.h
src/video/uikit/SDL_uikitwindow.m
--- a/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj	Wed Aug 06 00:45:11 2014 -0300
+++ b/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj	Wed Aug 06 03:24:16 2014 -0300
@@ -1274,8 +1274,14 @@
 		FD6526640DE8FCCB002AD96B /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
 				COPY_PHASE_STRIP = NO;
 				IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
+				GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
+				GCC_WARN_STRICT_SELECTOR_MATCH = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
 				PRODUCT_NAME = SDL2;
 				SKIP_INSTALL = YES;
 			};
@@ -1284,8 +1290,14 @@
 		FD6526650DE8FCCB002AD96B /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
 				COPY_PHASE_STRIP = YES;
 				IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
+				GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
+				GCC_WARN_STRICT_SELECTOR_MATCH = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
 				PRODUCT_NAME = SDL2;
 				SKIP_INSTALL = YES;
 			};
--- a/include/SDL_syswm.h	Wed Aug 06 00:45:11 2014 -0300
+++ b/include/SDL_syswm.h	Wed Aug 06 03:24:16 2014 -0300
@@ -209,9 +209,9 @@
         struct
         {
 #if defined(__OBJC__) && __has_feature(objc_arc)
-            NSWindow __unsafe_unretained *window; /* The Cocoa window */
+            NSWindow * __unsafe_unretained window; /* The Cocoa window */
 #else
-            NSWindow *window;                     /* The Cocoa window */
+            NSWindow *window;                      /* The Cocoa window */
 #endif
         } cocoa;
 #endif
@@ -219,9 +219,9 @@
         struct
         {
 #if defined(__OBJC__) && __has_feature(objc_arc)
-            UIWindow __unsafe_unretained *window; /* The UIKit window */
+            UIWindow * __unsafe_unretained window; /* The UIKit window */
 #else
-            UIWindow *window;                     /* The UIKit window */
+            UIWindow *window;                      /* The UIKit window */
 #endif
         } uikit;
 #endif
--- a/src/file/cocoa/SDL_rwopsbundlesupport.m	Wed Aug 06 00:45:11 2014 -0300
+++ b/src/file/cocoa/SDL_rwopsbundlesupport.m	Wed Aug 06 03:24:16 2014 -0300
@@ -50,8 +50,7 @@
         NSString* full_path_with_file_to_try = [resource_path stringByAppendingPathComponent:ns_string_file_component];
         if([file_manager fileExistsAtPath:full_path_with_file_to_try]) {
             fp = fopen([full_path_with_file_to_try fileSystemRepresentation], mode);
-        }
-        else {
+        } else {
             fp = fopen(file, mode);
         }
     }
--- a/src/joystick/iphoneos/SDL_sysjoystick.m	Wed Aug 06 00:45:11 2014 -0300
+++ b/src/joystick/iphoneos/SDL_sysjoystick.m	Wed Aug 06 03:24:16 2014 -0300
@@ -176,10 +176,7 @@
 SDL_SYS_JoystickQuit(void)
 {
     @autoreleasepool {
-        if (motionManager != nil) {
-            [motionManager release];
-            motionManager = nil;
-        }
+        motionManager = nil;
     }
 
     numjoysticks = 0;
--- a/src/video/uikit/SDL_uikitappdelegate.m	Wed Aug 06 00:45:11 2014 -0300
+++ b/src/video/uikit/SDL_uikitappdelegate.m	Wed Aug 06 03:24:16 2014 -0300
@@ -56,7 +56,7 @@
 
     /* Give over control to run loop, SDLUIKitDelegate will handle most things from here */
     @autoreleasepool {
-        UIApplicationMain(argc, argv, NULL, [SDLUIKitDelegate getAppDelegateClassName]);
+        UIApplicationMain(argc, argv, nil, [SDLUIKitDelegate getAppDelegateClassName]);
     }
 
     /* free the memory we used to hold copies of argc and argv */
@@ -94,26 +94,20 @@
         return nil;
     }
 
-    self->splash = [[UIImageView alloc] init];
-    [self setView:self->splash];
+    splash = [[UIImageView alloc] init];
+    self.view = splash;
 
     CGSize size = [UIScreen mainScreen].bounds.size;
     float height = SDL_max(size.width, size.height);
-    self->splashPortrait = [UIImage imageNamed:[NSString stringWithFormat:@"Default-%dh.png", (int)height]];
-    if (!self->splashPortrait) {
-        self->splashPortrait = [UIImage imageNamed:@"Default.png"];
+    splashPortrait = [UIImage imageNamed:[NSString stringWithFormat:@"Default-%dh.png", (int)height]];
+    if (!splashPortrait) {
+        splashPortrait = [UIImage imageNamed:@"Default.png"];
     }
-    self->splashLandscape = [UIImage imageNamed:@"Default-Landscape.png"];
-    if (!self->splashLandscape && self->splashPortrait) {
-        self->splashLandscape = [[UIImage alloc] initWithCGImage: self->splashPortrait.CGImage
-                                                           scale: 1.0
-                                                     orientation: UIImageOrientationRight];
-    }
-    if (self->splashPortrait) {
-        [self->splashPortrait retain];
-    }
-    if (self->splashLandscape) {
-        [self->splashLandscape retain];
+    splashLandscape = [UIImage imageNamed:@"Default-Landscape.png"];
+    if (!splashLandscape && splashPortrait) {
+        splashLandscape = [[UIImage alloc] initWithCGImage: splashPortrait.CGImage
+                                                     scale: 1.0
+                                               orientation: UIImageOrientationRight];
     }
 
     [self updateSplashImage:[[UIApplication sharedApplication] statusBarOrientation]];
@@ -148,9 +142,9 @@
     UIImage *image;
 
     if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
-        image = self->splashLandscape;
+        image = splashLandscape;
     } else {
-        image = self->splashPortrait;
+        image = splashPortrait;
     }
 
     if (image) {
@@ -192,8 +186,7 @@
 
     /* If we showed a splash image, clean it up */
     if (launch_window) {
-        [launch_window release];
-        launch_window = NULL;
+        launch_window = nil;
     }
 
     /* exit, passing the return status from the user's application */
--- a/src/video/uikit/SDL_uikitmessagebox.m	Wed Aug 06 00:45:11 2014 -0300
+++ b/src/video/uikit/SDL_uikitmessagebox.m	Wed Aug 06 03:24:16 2014 -0300
@@ -76,13 +76,14 @@
 
     @autoreleasepool {
         UIAlertView* alert = [[UIAlertView alloc] init];
+        UIKit_UIAlertViewDelegate *delegate = [[UIKit_UIAlertViewDelegate alloc] initWithButtonIndex:&clicked];
 
         alert.title = @(messageboxdata->title);
         alert.message = @(messageboxdata->message);
-        alert.delegate = [[UIKit_UIAlertViewDelegate alloc] initWithButtonIndex:&clicked];
+        alert.delegate = delegate;
 
         for (i = 0; i < messageboxdata->numbuttons; ++i) {
-            [alert addButtonWithTitle:[[NSString alloc] initWithUTF8String:buttons[i].text]];
+            [alert addButtonWithTitle:@(buttons[i].text)];
         }
 
         /* Set up for showing the alert */
@@ -100,8 +101,7 @@
 
         *buttonid = messageboxdata->buttons[clicked].buttonid;
 
-        [alert.delegate release];
-        [alert release];
+        alert.delegate = nil;
     }
 
     return 0;
--- a/src/video/uikit/SDL_uikitmodes.h	Wed Aug 06 00:45:11 2014 -0300
+++ b/src/video/uikit/SDL_uikitmodes.h	Wed Aug 06 03:24:16 2014 -0300
@@ -25,15 +25,17 @@
 
 #include "SDL_uikitvideo.h"
 
-typedef struct
-{
-    UIScreen *uiscreen;
-} SDL_DisplayData;
+@interface SDL_DisplayData : NSObject
+
+@property (nonatomic, strong) UIScreen *uiscreen;
+
+@end
 
-typedef struct
-{
-    UIScreenMode *uiscreenmode;
-} SDL_DisplayModeData;
+@interface SDL_DisplayModeData : NSObject
+
+@property (nonatomic, strong) UIScreenMode *uiscreenmode;
+
+@end
 
 extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen);
 
--- a/src/video/uikit/SDL_uikitmodes.m	Wed Aug 06 00:45:11 2014 -0300
+++ b/src/video/uikit/SDL_uikitmodes.m	Wed Aug 06 03:24:16 2014 -0300
@@ -25,25 +25,36 @@
 #include "SDL_assert.h"
 #include "SDL_uikitmodes.h"
 
+@implementation SDL_DisplayData
+
+@synthesize uiscreen;
+
+@end
+
+@implementation SDL_DisplayModeData
+
+@synthesize uiscreenmode;
+
+@end
+
 
 static int
 UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode,
     UIScreenMode * uiscreenmode)
 {
-    SDL_DisplayModeData *data = NULL;
+    SDL_DisplayModeData *data = nil;
 
     if (uiscreenmode != nil) {
         /* Allocate the display mode data */
-        data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
+        data = [[SDL_DisplayModeData alloc] init];
         if (!data) {
             return SDL_OutOfMemory();
         }
 
-        data->uiscreenmode = uiscreenmode;
-        [data->uiscreenmode retain];
+        data.uiscreenmode = uiscreenmode;
     }
 
-    mode->driverdata = data;
+    mode->driverdata = (void *) CFBridgingRetain(data);
 
     return 0;
 }
@@ -52,9 +63,7 @@
 UIKit_FreeDisplayModeData(SDL_DisplayMode * mode)
 {
     if (mode->driverdata != NULL) {
-        SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->driverdata;
-        [data->uiscreenmode release];
-        SDL_free(data);
+        CFRelease(mode->driverdata);
         mode->driverdata = NULL;
     }
 }
@@ -130,18 +139,18 @@
     display.current_mode = mode;
 
     /* Allocate the display data */
-    SDL_DisplayData *data = (SDL_DisplayData *) SDL_malloc(sizeof(*data));
+    SDL_DisplayData *data = [[SDL_DisplayData alloc] init];
     if (!data) {
         UIKit_FreeDisplayModeData(&display.desktop_mode);
         return SDL_OutOfMemory();
     }
 
-    [uiscreen retain];
-    data->uiscreen = uiscreen;
+    data.uiscreen = uiscreen;
 
-    display.driverdata = data;
+    display.driverdata = (void *) CFBridgingRetain(data);
     SDL_AddVideoDisplay(&display);
 
+
     return 0;
 }
 
@@ -173,14 +182,14 @@
 void
 UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
 {
-    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
+    @autoreleasepool {
+        SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
 
-    @autoreleasepool {
-        SDL_bool isLandscape = UIKit_IsDisplayLandscape(data->uiscreen);
-        SDL_bool addRotation = (data->uiscreen == [UIScreen mainScreen]);
-        CGFloat scale = data->uiscreen.scale;
+        SDL_bool isLandscape = UIKit_IsDisplayLandscape(data.uiscreen);
+        SDL_bool addRotation = (data.uiscreen == [UIScreen mainScreen]);
+        CGFloat scale = data.uiscreen.scale;
 
-        for (UIScreenMode *uimode in [data->uiscreen availableModes]) {
+        for (UIScreenMode *uimode in [data.uiscreen availableModes]) {
             /* The size of a UIScreenMode is in pixels, but we deal exclusively in
              * points (except in SDL_GL_GetDrawableSize.) */
             CGSize size = [uimode size];
@@ -203,19 +212,19 @@
 int
 UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
 {
-    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
-    SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
+    @autoreleasepool {
+        SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
+        SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)mode->driverdata;
 
-    @autoreleasepool {
-        [data->uiscreen setCurrentMode:modedata->uiscreenmode];
+        [data.uiscreen setCurrentMode:modedata.uiscreenmode];
 
-        if (data->uiscreen == [UIScreen mainScreen]) {
+        if (data.uiscreen == [UIScreen mainScreen]) {
             if (mode->w > mode->h) {
-                if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
+                if (!UIKit_IsDisplayLandscape(data.uiscreen)) {
                     [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
                 }
             } else if (mode->w < mode->h) {
-                if (UIKit_IsDisplayLandscape(data->uiscreen)) {
+                if (UIKit_IsDisplayLandscape(data.uiscreen)) {
                     [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
                 }
             }
@@ -240,10 +249,10 @@
                 UIKit_FreeDisplayModeData(mode);
             }
 
-            SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
-            [data->uiscreen release];
-            SDL_free(data);
-            display->driverdata = NULL;
+            if (display->driverdata != NULL) {
+                CFRelease(display->driverdata);
+                display->driverdata = NULL;
+            }
         }
     }
 }
--- a/src/video/uikit/SDL_uikitopengles.m	Wed Aug 06 00:45:11 2014 -0300
+++ b/src/video/uikit/SDL_uikitopengles.m	Wed Aug 06 03:24:16 2014 -0300
@@ -54,8 +54,8 @@
 {
     @autoreleasepool {
         if (context) {
-            SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
-            [data->view setCurrentContext];
+            SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+            [data.view setCurrentContext];
         }
         else {
             [EAGLContext setCurrentContext: nil];
@@ -67,14 +67,14 @@
 
 void UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
 {
-    SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+    @autoreleasepool {
+        SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
 
-    @autoreleasepool {
         if (w) {
-            *w = data->view.backingWidth;
+            *w = data.view.backingWidth;
         }
         if (h) {
-            *h = data->view.backingHeight;
+            *h = data.view.backingHeight;
         }
     }
 }
@@ -97,17 +97,17 @@
 void UIKit_GL_SwapWindow(_THIS, SDL_Window * window)
 {
     @autoreleasepool {
+        SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+
 #if SDL_POWER_UIKIT
         /* Check once a frame to see if we should turn off the battery monitor. */
         SDL_UIKit_UpdateBatteryMonitoring();
 #endif
 
-        SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
-
-        if (nil == data->view) {
+        if (data.view == nil) {
             return;
         }
-        [data->view swapBuffers];
+        [data.view swapBuffers];
 
         /* You need to pump events in order for the OS to make changes visible.
            We don't pump events here because we don't want iOS application events
@@ -121,8 +121,8 @@
 {
     @autoreleasepool {
         SDL_uikitopenglview *view;
-        SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
-        UIWindow *uiwindow = data->uiwindow;
+        SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+        UIWindow *uiwindow = data.uiwindow;
         CGRect frame = UIKit_ComputeViewFrame(window, uiwindow.screen);
         EAGLSharegroup *share_group = nil;
         CGFloat scale = 1.0;
@@ -136,7 +136,7 @@
         }
 
         if (_this->gl_config.share_with_current_context) {
-            SDL_uikitopenglview *view = (SDL_uikitopenglview *) SDL_GL_GetCurrentContext();
+            SDL_uikitopenglview *view = (__bridge SDL_uikitopenglview *) SDL_GL_GetCurrentContext();
             share_group = [view.context sharegroup];
         }
 
@@ -157,21 +157,20 @@
             return NULL;
         }
 
-        data->view = view;
-        view->viewcontroller = data->viewcontroller;
-        if (view->viewcontroller != nil) {
-            [view->viewcontroller setView:view];
-            [view->viewcontroller retain];
+        data.view = view;
+        view.viewcontroller = data.viewcontroller;
+        if (view.viewcontroller != nil) {
+            view.viewcontroller.view = view;
         }
         [uiwindow addSubview: view];
 
         /* The view controller needs to be the root in order to control rotation on iOS 6.0 */
         if (uiwindow.rootViewController == nil) {
-            uiwindow.rootViewController = view->viewcontroller;
+            uiwindow.rootViewController = view.viewcontroller;
         }
 
-        if (UIKit_GL_MakeCurrent(_this, window, view) < 0) {
-            UIKit_GL_DeleteContext(_this, view);
+        if (UIKit_GL_MakeCurrent(_this, window, (__bridge SDL_GLContext)(view)) < 0) {
+            UIKit_GL_DeleteContext(_this, (SDL_GLContext) CFBridgingRetain(view));
             return NULL;
         }
 
@@ -181,7 +180,7 @@
             SDL_SetKeyboardFocus(window);
         }
 
-        return view;
+        return (SDL_GLContext) CFBridgingRetain(view);
     }
 }
 
@@ -190,17 +189,15 @@
 {
     @autoreleasepool {
         /* the delegate has retained the view, this will release him */
-        SDL_uikitopenglview *view = (SDL_uikitopenglview *)context;
-        if (view->viewcontroller) {
+        SDL_uikitopenglview *view = (SDL_uikitopenglview *)CFBridgingRelease(context);
+        if (view.viewcontroller) {
             UIWindow *uiwindow = (UIWindow *)view.superview;
-            if (uiwindow.rootViewController == view->viewcontroller) {
+            if (uiwindow.rootViewController == view.viewcontroller) {
                 uiwindow.rootViewController = nil;
             }
-            [view->viewcontroller setView:nil];
-            [view->viewcontroller release];
+            view.viewcontroller.view = nil;
         }
         [view removeFromSuperview];
-        [view release];
     }
 }
 
--- a/src/video/uikit/SDL_uikitopenglview.h	Wed Aug 06 00:45:11 2014 -0300
+++ b/src/video/uikit/SDL_uikitopenglview.h	Wed Aug 06 03:24:16 2014 -0300
@@ -44,7 +44,7 @@
        majorVersion:(int)majorVersion
          shareGroup:(EAGLSharegroup*)shareGroup;
 
-@property (nonatomic, retain, readonly) EAGLContext *context;
+@property (nonatomic, strong, readonly) EAGLContext *context;
 
 /* The width and height of the drawable in pixels (as opposed to points.) */
 @property (nonatomic, readonly) int backingWidth;
--- a/src/video/uikit/SDL_uikitopenglview.m	Wed Aug 06 00:45:11 2014 -0300
+++ b/src/video/uikit/SDL_uikitopenglview.m	Wed Aug 06 03:24:16 2014 -0300
@@ -85,7 +85,6 @@
 
         context = [[EAGLContext alloc] initWithAPI:api sharegroup:shareGroup];
         if (!context || ![EAGLContext setCurrentContext:context]) {
-            [self release];
             SDL_SetError("OpenGL ES %d not supported", majorVersion);
             return nil;
         }
@@ -118,7 +117,6 @@
         glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
 
         if (![context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:eaglLayer]) {
-            [self release];
             SDL_SetError("Failed creating OpenGL ES drawable");
             return nil;
         }
@@ -154,7 +152,6 @@
         }
 
         if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
-            [self release];
             SDL_SetError("Failed creating OpenGL ES framebuffer");
             return nil;
         }
@@ -268,12 +265,10 @@
 
 - (void)dealloc
 {
-    [self destroyFramebuffer];
     if ([EAGLContext currentContext] == context) {
+        [self destroyFramebuffer];
         [EAGLContext setCurrentContext:nil];
     }
-    [context release];
-    [super dealloc];
 }
 
 @end
--- a/src/video/uikit/SDL_uikitview.h	Wed Aug 06 00:45:11 2014 -0300
+++ b/src/video/uikit/SDL_uikitview.h	Wed Aug 06 03:24:16 2014 -0300
@@ -31,13 +31,12 @@
 #endif
 
 #if SDL_IPHONE_KEYBOARD
-@interface SDL_uikitview : UIView<UITextFieldDelegate> {
+@interface SDL_uikitview : UIView <UITextFieldDelegate>
 #else
-@interface SDL_uikitview : UIView {
+@interface SDL_uikitview : UIView
 #endif
-@public
-    SDL_uikitviewcontroller *viewcontroller;
-}
+
+@property (nonatomic, weak) SDL_uikitviewcontroller *viewcontroller;
 
 - (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize;
 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
--- a/src/video/uikit/SDL_uikitview.m	Wed Aug 06 00:45:11 2014 -0300
+++ b/src/video/uikit/SDL_uikitview.m	Wed Aug 06 03:24:16 2014 -0300
@@ -51,6 +51,8 @@
 
 }
 
+@synthesize viewcontroller;
+
 - (id)initWithFrame:(CGRect)frame
 {
     if (self = [super initWithFrame: frame]) {
@@ -88,10 +90,10 @@
             CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
 
             /* send moved event */
-            SDL_SendMouseMotion(viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
+            SDL_SendMouseMotion(self.viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
 
             /* send mouse down event */
-            SDL_SendMouseButton(viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
+            SDL_SendMouseButton(self.viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
 
             leftFingerDown = touch;
         }
@@ -123,7 +125,7 @@
     for (UITouch *touch in touches) {
         if (touch == leftFingerDown) {
             /* send mouse up */
-            SDL_SendMouseButton(viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
+            SDL_SendMouseButton(self.viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
             leftFingerDown = nil;
         }
 
@@ -162,7 +164,7 @@
             CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
 
             /* send moved event */
-            SDL_SendMouseMotion(viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
+            SDL_SendMouseMotion(self.viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
         }
 
         CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
@@ -212,7 +214,6 @@
     keyboardVisible = NO;
     /* add the UITextField (hidden) to our view */
     [self addSubview: textField];
-    [textField release];
     
     _uikit_keyboard_init();
 }
@@ -301,8 +302,8 @@
         return nil;
     }
 
-    SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
-    SDL_uikitview *view = data != NULL ? data->view : nil;
+    SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+    SDL_uikitview *view = data != nil ? data.view : nil;
 
     if (view == nil) {
         SDL_SetError("Window has no view");
@@ -352,11 +353,11 @@
 void _uikit_keyboard_update() {
     SDL_Window *window = SDL_GetFocusWindow();
     if (!window) { return; }
-    SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+    SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
     if (!data) { return; }
-    SDL_uikitview *view = data->view;
+    SDL_uikitview *view = data.view;
     if (!view) { return; }
-    
+
     SDL_Rect r = view.textInputRect;
     int height = view.keyboardHeight;
     int offsetx = 0;
--- a/src/video/uikit/SDL_uikitwindow.h	Wed Aug 06 00:45:11 2014 -0300
+++ b/src/video/uikit/SDL_uikitwindow.h	Wed Aug 06 03:24:16 2014 -0300
@@ -26,8 +26,6 @@
 #import "SDL_uikitopenglview.h"
 #import "SDL_uikitviewcontroller.h"
 
-typedef struct SDL_WindowData SDL_WindowData;
-
 extern int UIKit_CreateWindow(_THIS, SDL_Window * window);
 extern void UIKit_ShowWindow(_THIS, SDL_Window * window);
 extern void UIKit_HideWindow(_THIS, SDL_Window * window);
@@ -44,12 +42,13 @@
 
 @end
 
-struct SDL_WindowData
-{
-    SDL_uikitwindow *uiwindow;
-    SDL_uikitopenglview *view;
-    SDL_uikitviewcontroller *viewcontroller;
-};
+@interface SDL_WindowData : NSObject
+
+@property (nonatomic, strong) SDL_uikitwindow *uiwindow;
+@property (nonatomic, strong) SDL_uikitopenglview *view;
+@property (nonatomic, strong) SDL_uikitviewcontroller *viewcontroller;
+
+@end
 
 #endif /* _SDL_uikitwindow_h */
 
--- a/src/video/uikit/SDL_uikitwindow.m	Wed Aug 06 00:45:11 2014 -0300
+++ b/src/video/uikit/SDL_uikitwindow.m	Wed Aug 06 03:24:16 2014 -0300
@@ -56,35 +56,41 @@
 
 @end
 
+@implementation SDL_WindowData
+
+@synthesize uiwindow;
+@synthesize view;
+@synthesize viewcontroller;
+
+@end
+
 
 static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow, SDL_bool created)
 {
     SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
-    SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
-    SDL_WindowData *data;
+    SDL_DisplayData *displaydata = (__bridge SDL_DisplayData *) display->driverdata;
 
     /* Allocate the window data */
-    data = (SDL_WindowData *)SDL_malloc(sizeof(*data));
+    SDL_WindowData *data = [[SDL_WindowData alloc] init];
     if (!data) {
         return SDL_OutOfMemory();
     }
-    data->uiwindow = uiwindow;
-    data->viewcontroller = nil;
-    data->view = nil;
+
+    data.uiwindow = uiwindow;
 
     /* Fill in the SDL window with the window data */
     {
         window->x = 0;
         window->y = 0;
 
-        CGRect frame = UIKit_ComputeViewFrame(window, displaydata->uiscreen);
+        CGRect frame = UIKit_ComputeViewFrame(window, displaydata.uiscreen);
 
         /* Get frame dimensions */
         int width = (int) frame.size.width;
         int height = (int) frame.size.height;
 
         /* Make sure the width/height are oriented correctly */
-        if (UIKit_IsDisplayLandscape(displaydata->uiscreen) != (width > height)) {
+        if (UIKit_IsDisplayLandscape(displaydata.uiscreen) != (width > height)) {
             int temp = width;
             width = height;
             height = temp;
@@ -94,7 +100,7 @@
         window->h = height;
     }
 
-    window->driverdata = data;
+    window->driverdata = (void *) CFBridgingRetain(data);
 
     /* only one window on iOS, always shown */
     window->flags &= ~SDL_WINDOW_HIDDEN;
@@ -103,7 +109,7 @@
      * This is only set if the window is on the main screen. Other screens
      *  just force the window to have the borderless flag.
      */
-    if (displaydata->uiscreen == [UIScreen mainScreen]) {
+    if (displaydata.uiscreen == [UIScreen mainScreen]) {
         window->flags |= SDL_WINDOW_INPUT_FOCUS;  /* always has input focus */
 
         /* This was setup earlier for our window, and in iOS 7 is controlled by the view, not the application
@@ -123,8 +129,8 @@
      * device orientation changes. This will trigger resize events, if
      * appropriate.
      */
-    data->viewcontroller = [[SDL_uikitviewcontroller alloc] initWithSDLWindow:window];
-    [data->viewcontroller setTitle:@"SDL App"];  /* !!! FIXME: hook up SDL_SetWindowTitle() */
+    data.viewcontroller = [[SDL_uikitviewcontroller alloc] initWithSDLWindow:window];
+    data.viewcontroller.title = @"SDL App";  /* !!! FIXME: hook up SDL_SetWindowTitle() */
 
     return 0;
 }
@@ -134,9 +140,9 @@
 {
     @autoreleasepool {
         SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
-        SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
-        const BOOL external = ([UIScreen mainScreen] != data->uiscreen);
-        const CGSize origsize = [[data->uiscreen currentMode] size];
+        SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
+        const BOOL external = ([UIScreen mainScreen] != data.uiscreen);
+        const CGSize origsize = [[data.uiscreen currentMode] size];
 
         /* SDL currently puts this window at the start of display's linked list. We rely on this. */
         SDL_assert(_this->windows == window);
@@ -164,8 +170,8 @@
             }
 
             if (bestmode) {
-                SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)bestmode->driverdata;
-                [data->uiscreen setCurrentMode:modedata->uiscreenmode];
+                SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)bestmode->driverdata;
+                [data.uiscreen setCurrentMode:modedata.uiscreenmode];
 
                 /* desktop_mode doesn't change here (the higher level will
                  * use it to set all the screens back to their defaults
@@ -175,7 +181,7 @@
             }
         }
 
-        if (data->uiscreen == [UIScreen mainScreen]) {
+        if (data.uiscreen == [UIScreen mainScreen]) {
             if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
                 [UIApplication sharedApplication].statusBarHidden = YES;
             } else {
@@ -185,11 +191,11 @@
 
         if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
             if (window->w > window->h) {
-                if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
+                if (!UIKit_IsDisplayLandscape(data.uiscreen)) {
                     [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
                 }
             } else if (window->w < window->h) {
-                if (UIKit_IsDisplayLandscape(data->uiscreen)) {
+                if (UIKit_IsDisplayLandscape(data.uiscreen)) {
                     [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
                 }
             }
@@ -197,7 +203,7 @@
 
         /* ignore the size user requested, and make a fullscreen window */
         /* !!! FIXME: can we have a smaller view? */
-        SDL_uikitwindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data->uiscreen.bounds];
+        SDL_uikitwindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data.uiscreen.bounds];
 
         /* put the window on an external display if appropriate. This implicitly
          * does [uiwindow setframe:[uiscreen bounds]], so don't do it on the
@@ -205,13 +211,13 @@
          * status bar real estate.
          */
         if (external) {
-            [uiwindow setScreen:data->uiscreen];
+            [uiwindow setScreen:data.uiscreen];
         }
 
         if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
-            [uiwindow release];
             return -1;
         }
+
     }
 
     return 1;
@@ -221,7 +227,7 @@
 UIKit_ShowWindow(_THIS, SDL_Window * window)
 {
     @autoreleasepool {
-        UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
+        UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow;
 
         [uiwindow makeKeyAndVisible];
     }
@@ -231,7 +237,7 @@
 UIKit_HideWindow(_THIS, SDL_Window * window)
 {
     @autoreleasepool {
-        UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
+        UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow;
 
         uiwindow.hidden = YES;
     }
@@ -251,11 +257,11 @@
 static void
 UIKit_UpdateWindowBorder(_THIS, SDL_Window * window)
 {
-    SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata;
-    SDL_uikitviewcontroller *viewcontroller = windowdata->viewcontroller;
+    SDL_WindowData *windowdata = (__bridge SDL_WindowData *) window->driverdata;
+    SDL_uikitviewcontroller *viewcontroller = windowdata.viewcontroller;
     CGRect frame;
 
-    if (windowdata->uiwindow.screen == [UIScreen mainScreen]) {
+    if (windowdata.uiwindow.screen == [UIScreen mainScreen]) {
         if (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS)) {
             [UIApplication sharedApplication].statusBarHidden = YES;
         } else {
@@ -269,11 +275,11 @@
     }
 
     /* Update the view's frame to account for the status bar change. */
-    frame = UIKit_ComputeViewFrame(window, windowdata->uiwindow.screen);
+    frame = UIKit_ComputeViewFrame(window, windowdata.uiwindow.screen);
 
-    windowdata->view.frame = frame;
-    [windowdata->view setNeedsLayout];
-    [windowdata->view layoutIfNeeded];
+    windowdata.view.frame = frame;
+    [windowdata.view setNeedsLayout];
+    [windowdata.view layoutIfNeeded];
 
     /* Get frame dimensions */
     int width  = (int) frame.size.width;
@@ -308,13 +314,9 @@
 void
 UIKit_DestroyWindow(_THIS, SDL_Window * window)
 {
-    SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
-
     @autoreleasepool {
-        if (data) {
-            [data->viewcontroller release];
-            [data->uiwindow release];
-            SDL_free(data);
+        if (window->driverdata != NULL) {
+            CFRelease(window->driverdata);
         }
     }
 
@@ -325,7 +327,7 @@
 UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
 {
     @autoreleasepool {
-        UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
+        UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow;
 
         if (info->version.major <= SDL_MAJOR_VERSION) {
             info->subsystem = SDL_SYSWM_UIKIT;
@@ -342,14 +344,14 @@
 int
 SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam)
 {
-    SDL_WindowData *data = window ? (SDL_WindowData *)window->driverdata : NULL;
+    @autoreleasepool {
+        SDL_WindowData *data = window ? (__bridge SDL_WindowData *)window->driverdata : nil;
 
-    if (!data || !data->view) {
-        return SDL_SetError("Invalid window or view not set");
-    }
+        if (!data || !data.view) {
+            return SDL_SetError("Invalid window or view not set");
+        }
 
-    @autoreleasepool {
-        [data->view setAnimationCallback:interval callback:callback callbackParam:callbackParam];
+        [data.view setAnimationCallback:interval callback:callback callbackParam:callbackParam];
     }
 
     return 0;