Нет утечек. Но вы выделяете новый массив и строку для каждого цикла, который будет накапливаться, когда ввод будет очень длинным, прежде чем пул авто-выпуска сможет истощиться.
while ( ![scanner isAtEnd] ) {
BOOL insideQuotes = NO;
BOOL finishedRow = NO;
NSMutableArray *columns = [NSMutableArray arrayWithCapacity:10];
NSMutableString *currentColumn = [NSMutableString string];
Поскольку это временные переменные, вы можете просто переместить их за пределы цикла и сбросить их на итерации.
NSMutableArray *columns = [NSMutableArray arrayWithCapacity:10];
NSMutableString *currentColumn = [NSMutableString string];
while ( ![scanner isAtEnd] ) {
BOOL insideQuotes = NO;
BOOL finishedRow = NO;
[columns removeAllObjects];
[currentColumn setString:@""];