Resolved variable arguments help (Cocoa format string)

Discussion in 'Mac Programming' started by ArtOfWarfare, Apr 30, 2013.

  1. ArtOfWarfare, Apr 30, 2013
    Last edited: May 1, 2013

    macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #1
    I've written a category on NSString that includes this:

    Code:
    // From what I can tell, NSString's default localizedStringWithFormat: method
    // doesn't actually do a lookup on Localizable.strings. So I wrote this which
    // does the lookup and then does everything the default one does.
    
    + (NSString *)fullyLocalizedStringWithFormat:(NSString *)format, ...
    {
        NSString *lookup = NSLocalizedString(format, @"");
        NSString *fullyLocalized;
    
        va_list arguments;
        va_start(arguments, format);
    
        NSLogv(lookup, arguments);
        fullyLocalized = [NSString localizedStringWithFormat:lookup, arguments];
    
        va_end(arguments);
        return fullyLocalized;
    }
    If I invoke it with:

    Code:
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.dateStyle = NSDateFormatterShortStyle;
    dateFormatter.timeStyle = NSDateFormatterNoStyle;
    dateFormatter.locale = [NSLocale currentLocale];
    [NSString fullyLocalizedStringWithFormat:@"Replaced %@", [dateFormatter stringFromDate:[NSDate date]]];
    And I have this in Localizable.strings:
    Code:
    "Replaced %@" = "Batteries were Last Full: %@";
    Then NSLogv will (today in the US) properly print out
    "Batteries were Last Full: 4/30/13"

    But on the very next line, localizedStringWithFormat: crashes my program with EXC_BAD_ACCESS

    If I replaced localizedStringWithFormat: with stringWithFormat:, it crashes just the same.

    It also crashes if I replace it with:

    Code:
    fullyLocalized = [[NSString alloc] initWithFormat:lookup arguments:arguments];
    Suggestions?

    Edit: I found one thing that doesn't crash so far:

    Code:
    + (NSString *)fullyLocalizedStringWithFormat:(NSString *)format, ...
    {
        NSString *lookup = NSLocalizedString(format, @"");
        NSString *fullyLocalized;
        va_list arguments;
        va_start(arguments, format);
        //NSLogv(lookup, arguments);
        fullyLocalized = [[NSString alloc] initWithFormat:lookup arguments:arguments];
        va_end(arguments);
        return fullyLocalized;
    }
    NSLogv can't be there or it doesn't work. I still can't make it localize the arguments at the same time, though (IE, use [localizedStringWithFormat:lookup, arguments]; ).

    Exit 2x: This appears to work, but the documentation confuses me a little so I'm not sure if it's actually working the way I want it to or if it just looks like it is for my local:

    Code:
    + (NSString *)fullyLocalizedStringWithFormat:(NSString *)format, ...
    {
        NSString *lookup = NSLocalizedString(format, @"");
        NSString *fullyLocalized;
        va_list arguments;
        va_start(arguments, format);
        fullyLocalized = [[NSString alloc] initWithFormat:lookup
                                                   locale:nil
                                                arguments:arguments];
        va_end(arguments);
        return [fullyLocalized autorelease];
    }
    The documentation for initWithFormat:locale:arguments: says, pertaining to locale:
    Is the canonical locale what I want?

    Afterwards it says:
    The current user's locale is exactly what I want, but I'm really confused how exactly the method they provide would do anything like that... standardUserDefaults doesn't contain anything about the current user's locale (as far as I know), so it makes no sense to me and sounds like a typo.

    Edit 3x: I've decided to use

    Code:
    + (NSString *)fullyLocalizedStringWithFormat:(NSString *)format, ...
    {
        NSString *lookup = NSLocalizedString(format, @"");
        NSString *fullyLocalized;
        va_list arguments;
        va_start(arguments, format);
        fullyLocalized = [[NSString alloc] initWithFormat:lookup
                                                   locale:[NSLocale currentLocale]
                                                arguments:arguments];
        va_end(arguments);
        return [fullyLocalized autorelease];
    }
    It appears to work, it doesn't confuse me, and it seems to make sense.
     
  2. macrumors G5

    gnasher729

    Joined:
    Nov 25, 2005
    #2
    You can't use a va_list twice in two calls as you did in your very first method; the first called function will modify it, and then the second one won't work. You need to use a sequence va_start / use it / va_end, va_start, use it again, va_end.
     

Share This Page