ARC `BAD _ACCESS `при использовании метода категории NSString

Я называю свой служебный метод так:

NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"dd.MM.yy HH:mm"];
NSString *dateString = [dateFormat stringFromDate:[NSDate date]];

return [[Environment sharedInstance].versionLabelFormat replaceTokensWithStrings:
     @"VERSION", APP_VERSION, 
     @"BUILD", APP_BULD_NUMBER, 
     @"DATETIME", dateString, 
     nil ];

Это метод категорий NSString

-(NSString *)replaceTokensWithStrings:(NSString *)firstKey,... NS_REQUIRES_NIL_TERMINATION{

    NSString *result = self;

        va_list _arguments;
        va_start(_arguments, firstKey);

        for (NSString *key = firstKey; key != nil; key = va_arg(_arguments, NSString*)) {

            // The value has to be copied to prevent crashes
            NSString *value = [(NSString *)(va_arg(_arguments, NSString*))copy];

            if(!value){
                // Every key has to have a value pair otherwise the replacement is invalid and nil is returned

                NSLog(@"Premature occurence of nil. Each token must be accompanied by a value: %@", result);
                return nil;
            }

            result = [result replaceToken:key withString:value];
        }
        va_end(_arguments);

    // Check if there are any tokens which were not yet replaced (for example if one value was nil)

    if([result rangeOfString:@"{"].location == NSNotFound){
        return result;
    } else {
        NSLog(@"Failed to replace tokens failed string still contains tokens: %@", result);
        return nil;
    }
}

. Нет, в следующей строке мне пришлось добавить оператор copy, иначе был бы Зомби сdateString:

NSString *value = [(NSString *)(va_arg(_arguments, NSString*))copy];

Чтобы быть более точным, Отчет о Зомби сказал мне следующее:

 1 Malloc       NSDateFormatter stringForObjectValue:
   Autorelease  NSDateFormatter stringForObjectValue:
 2 CFRetain     MyClass versionString:
 3 CFRetain     replaceToken:withString:
 2 CFRelease    replaceToken:withString:
 1 CFRelease    replaceTokensWithStrings:   ( One release too much!)
 0 CFRelease    MyClass versionString:
-1 Zombie       GSEventRunModal

Хотя оператор copy, кажется, решает проблему, я хотел бы понять, что не соответствует ARC -коду, чтобы BAD_ACCESSвозникало без copyдля строки значения.

7
задан Besi 20 July 2012 в 09:09
поделиться