Răsfoiți Sursa

Explicitly retain and release NSObjects in C structures

Fixes https://github.com/libsdl-org/SDL/issues/9021
Fixes https://github.com/libsdl-org/SDL/issues/9042

(cherry picked from commit 42cdbf6b214a4a4b614e6086d80bb12a1fce32be)
(cherry picked from commit 971c5c26106fe0498c601b71009e82303188d1e9)
Sam Lantinga 1 an în urmă
părinte
comite
0fb294ade4
1 a modificat fișierele cu 17 adăugiri și 6 ștergeri
  1. 17 6
      src/joystick/iphoneos/SDL_mfijoystick.m

+ 17 - 6
src/joystick/iphoneos/SDL_mfijoystick.m

@@ -510,7 +510,7 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
         NSDictionary<NSString *, GCControllerElement *> *elements = controller.physicalInputProfile.elements;
 
         /* Provide both axes and analog buttons as SDL axes */
-        device->axes = [[[elements allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]
+        NSArray *axes = [[[elements allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]
                                          filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings) {
             GCControllerElement *element;
 
@@ -527,8 +527,7 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
             }
             return NO;
         }]];
-        device->naxes = (int)device->axes.count;
-        device->buttons = [[[elements allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]
+        NSArray *buttons = [[[elements allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]
                                             filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings) {
             GCControllerElement *element;
 
@@ -542,7 +541,12 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
             }
             return NO;
         }]];
-        device->nbuttons = (int)device->buttons.count;
+        /* Explicitly retain the arrays because SDL_JoystickDeviceItem is a
+         * struct, and ARC doesn't work with structs. */
+        device->naxes = (int)axes.count;
+        device->axes = (__bridge NSArray *)CFBridgingRetain(axes);
+        device->nbuttons = (int)buttons.count;
+        device->buttons = (__bridge NSArray *)CFBridgingRetain(buttons);
         subtype = 4;
 
 #ifdef DEBUG_CONTROLLER_PROFILE
@@ -779,13 +783,20 @@ static SDL_JoystickDeviceItem *IOS_RemoveJoystickDevice(SDL_JoystickDeviceItem *
 
 #ifdef SDL_JOYSTICK_MFI
     @autoreleasepool {
+        /* These were explicitly retained in the struct, so they should be explicitly released before freeing the struct. */
         if (device->controller) {
-            /* The controller was explicitly retained in the struct, so it
-             * should be explicitly released before freeing the struct. */
             GCController *controller = CFBridgingRelease((__bridge CFTypeRef)(device->controller));
             controller.controllerPausedHandler = nil;
             device->controller = nil;
         }
+        if (device->axes) {
+            NSArray *axes = CFBridgingRelease((__bridge CFTypeRef)(device->axes));
+            device->axes = nil;
+        }
+        if (device->buttons) {
+            NSArray *buttons = CFBridgingRelease((__bridge CFTypeRef)(device->buttons));
+            device->buttons = nil;
+        }
     }
 #endif /* SDL_JOYSTICK_MFI */