Подтвердить что ты не робот

Разница между литералами NSString

В чем разница между этими двумя строками?

NSString * string = @"My String";
NSString * string = [[[NSString alloc] initWithString:@"MyString"] autorelease]
4b9b3361

Ответ 1

@ "My String" - это буквальная строка, скомпилированная в двоичный файл. При загрузке он имеет место в памяти. Первая строка объявляет переменную, указывающую на эту точку в памяти.

Из руководства по программированию строк:

Самый простой способ создать строковый объект в исходном коде - использовать конструкцию Objective-C @ "...":

NSString *temp = @"/tmp/scratch"; 

Обратите внимание, что при создании строки постоянным таким образом, вам следует избегать использования чего-либо, кроме 7-битного Символы ASCII. Такой объект создается во время компиляции и существует во время выполнения ваших программ. Компилятор делает такой объект константы, уникальные для каждого модуля, и они никогда не освобождаются, хотя вы можете сохранить и освободить их, как и любой другой объект.

Вторая строка выделяет строку, беря эту литеральную строку. Обратите внимание, что буквальные строки "My String" одинаковы. Чтобы доказать это:

NSString *str = @"My String";
NSLog(@"%@ (%p)", str, str);

NSString *str2 = [[NSString alloc] initWithString:@"My String"];
NSLog(@"%@ (%p)", str2, str2);

NSString *copy = [str2 stringByAppendingString:@"2"];
NSLog(@"%@ (%p)", copy, copy);

Выводит тот же адрес памяти:

2011-11-07 07:11:26.172 Craplet[5433:707] My String (0x100002268)
2011-11-07 07:11:26.174 Craplet[5433:707] My String (0x100002268)
2011-11-07 07:11:26.174 Craplet[5433:707] My String2 (0x1003002a0)

То, что говорит, это не только первые две строки одного и того же адреса памяти, но если вы не меняете код, это тот же адрес памяти каждый раз, когда вы его запускаете. Это то же двоичное смещение в памяти. Но не только копия различна, но и различна при каждом ее запуске, так как она выделяется в куче.

Автореферат не влияет на приведенный выше документ doc. Вы можете освободить их, но они никогда не освобождаются. Таким образом, они равны не потому, что обе являются автореализованной строкой, но они оба являются константами, и релиз игнорируется.

Ответ 2

Один - это буквальная строка, которая сохраняется для жизни исполняемого приложения. Другой может быть динамическим объектом, который сохраняется только до автоустановки. (Это может быть и буквальная строка, если система решает оптимизировать ее таким образом - нет гарантий, она не будет.)

Ответ 3

bryanmac на 100% прав в своем ответе. Я просто добавил явный пример, используя GHUnit.

NSString creation - literal vs nonliteral.

Показывает строки, созданные разными способами, если они являются буквальными или нелитеративными.

- (void) test_stringCreation
{
    NSString *literalString = @"literalString";
    NSString *referenced = literalString;
    NSString *copy = [literalString copy];
    NSString *initWithString = [[NSString alloc] initWithString:literalString];
    NSString *initWithFormat = [[NSString alloc] initWithFormat:@"%@", literalString];

    // Testing that the memory addresses of referenced objects are the same.
    GHAssertEquals(literalString, @"literalString", @"literal");
    GHAssertEquals(referenced, @"literalString", @"literal");
    GHAssertEquals(copy, @"literalString", @"literal");
    GHAssertEquals(initWithString, @"literalString", @"literal");
    GHAssertNotEquals(initWithFormat, @"literalString",
                      @"nonliteral - referenced objects' memory addresses are \
                      different.");

    // Testing that the objects referenced are equal, i.e. isEqual: .
    GHAssertEqualObjects(literalString, @"literalString", nil);
    GHAssertEqualObjects(referenced, @"literalString", nil);
    GHAssertEqualObjects(copy, @"literalString", nil);
    GHAssertEqualObjects(initWithString, @"literalString", nil);
    GHAssertEqualObjects(initWithFormat, @"literalString", nil);

    // Testing that the strings referenced are the same, i.e. isEqualToString: .
    GHAssertEqualStrings(literalString, @"literalString", nil);
    GHAssertEqualStrings(referenced, @"literalString", nil);
    GHAssertEqualStrings(copy, @"literalString", nil);
    GHAssertEqualStrings(initWithString, @"literalString", nil);
    GHAssertEqualStrings(initWithFormat, @"literalString", nil);
}

Ответ 4

Между ними нет никакой разницы. Строка, инициированная тем, как вы показали в первом примере, - это строка с автореализацией.

Ответ 5

Просто запомните эту основную вещь: -

NSString *string = ...

Это указатель на объект, "не объект"!

Следовательно, оператор: NSString *string = @"Hello"; присваивает адрес объекта @"Hello" строке указателя.

@"Hello" интерпретируется как константная строка компилятором, и сам компилятор выделяет для нее память.

Аналогично, статут

NSObject *myObject = somethingElse;

присваивает адрес somethingElse указателю myObject и что somethingElse уже должен быть назначен инициатором объявления.

Следовательно, оператор: NSObject *myObject = [[NSObject alloc] init]; выделяет и инициализирует объект NSObject и присваивает свой адрес myObject.