New Crash After Building With Swift 5.5 / Xcode 14


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.

Not sure this will help but: you do no need the double pointers NSMutableArray **, you can replace it with NSMutableArray * and remove the * from *projectsArray and *frameworksArray.

NSMutableArray** and NSMutableArray* are two very different things.

The plot thickens: the crash happens only when the Swift compiler is set to -O (speed) optimization in Xcode 14 beta 5 (and presumably the earlier Xcode 14 betas as well).

I'm not sure why you're saying that. What I meant is that you can rewrite your objc code to take NSMutableArray* since you are actually not making use of passing NSMutableArray**, it might not explain the crash or bug in the compiler but it could maybe provide a way to work around it.

Since swift prefers value type rather than reference type. It’s possible swift will release heap memory faster. My suggestion is making a local copy before entering iteration loop.