Context
I have an Objective-C method from 2009. Its job is to fetch two types of entities from a Core Data store and then separate those entities into two different arrays (LPFramework
is a subclass of LPProject
):
- (void) populateArraysWithProjects:(NSMutableArray **)projectsArray andFrameworks:(NSMutableArray **)frameworksArray
{
[*projectsArray removeAllObjects];
[*frameworksArray removeAllObjects];
NSManagedObjectModel *model = [[self persistentStoreCoordinator] managedObjectModel];
NSFetchRequest *fetch = [model fetchRequestFromTemplateWithName:@"FetchAllProjectsAndFrameworks" substitutionVariables:@{}];
NSArray *results = [self.mainMOC executeFetchRequest:fetch error:NULL];
for (LPProject *item in results)
{
if ([item isKindOfClass:[LPFramework class]]) {
[*frameworksArray addObject:item];
} else {
[*projectsArray addObject:item];
}
}
}
The Problem
In a Swift class, I use this method as follows:
var projects: NSMutableArray = NSMutableArray(capacity: 50)
var frameworks: NSMutableArray = NSMutableArray(capacity: 50)
modelController.populateArrays(withProjects: &projects, andFrameworks: &frameworks)
let targetArray: NSMutableArray = (someCondition == true) ? frameworks : projects
for item in targetArray {
// Do stuff
}
This has worked for many years. There are no warnings in Xcode. Suddenly, however, when I build the app using Swift 5.5 and Xcode 14, I get an EXC_BAD_ACCESS
crash when attempting to use targetArray
. It's as if ARC is now releasing the memory too soon.
I have a few places where I use this method in Objective-C with manual memory management. It continues to work correctly there.
Has something changed in the latest release of Swift that would cause this new behavior? Versions of the app built with older versions of the Swift compiler do not exhibit this crash—even when the -populateArrays
method is used from Swift code.