Распределение и выпуск проблемы - PullRequest
1 голос
/ 12 сентября 2011

Я пытаюсь объяснить управление памятью на iOS другу и показываю ему неправильный код. Но когда я запускаю приложение, оно работает, и я не знаю почему. Вот фрагмент:

NSString *myString = [[NSString alloc] initWithString:@"myString"];
[myString release];
NSLog(@"%@",myString);

Я не понимаю, почему мой NSLog работает ... У вас есть объяснения?

Спасибо!

Ответы [ 2 ]

3 голосов
/ 12 сентября 2011

В отношении вашего примера необходимо помнить две вещи.

  1. Как объяснил MByD, доступ к объекту, который был освобожден, является неопределенным поведением.Это может или не может привести к сбою вашей программы - это зависит от того, была ли память, которая была выделена для этого объекта, была повторно использована и что было помещено туда.В некоторых случаях память еще не была повторно использована (и вы могли бы подумать, что объект все еще жив, но этот объект на самом деле является призрачным объектом ), в других случаях память могла быть повторно использована другой Целью-C объект (программа не будет аварийно завершать работу, но вы увидите другой объект), и в других случаях память может быть повторно использована чем-то, что не является объектом Objective-C (в этом случае программа, скорее всего, - но не обязательно- крах).

  2. Ваш строковый объект является константной строкой.Как объяснено в ответе на этот вопрос и его комментариях, константная строка никогда не освобождается.Когда вы отправляете -[NSString initWithString:], передавая константную строку в качестве аргумента, Какао возвращает исходную константную строку, поэтому ваш код фактически совпадает с NSString *myString = @"myString";.Это внутренняя деталь реализации Какао, хотя.Производственный код должен всегда учитывать, что объекты, возвращаемые +alloc (и, как правило, последующие -init), принадлежат вызывающей стороне, должны быть освобождены, когда вызывающая сторона больше не заинтересована в них, и не будут доступны после освобождения.

Ради эксперимента попробуйте следующий код:

#import <Foundation/Foundation.h>
#include <stdio.h>

int main(void) {
    [NSAutoreleasePool new];

    NSString *s1 = [[NSString alloc] initWithString:@"myString"];
    NSString *s2 = [[NSString alloc] initWithString:@"myString"];
    NSString *s3 = [[NSString alloc] initWithString:@"myString"];
    NSString *s4 = [[NSString alloc] initWithString:@"myString"];

    printf("s1 = %p\n", s1);
    printf("s2 = %p\n", s2);
    printf("s3 = %p\n", s3);
    printf("s4 = %p\n", s4);

    [s1 release];
    [s2 release];
    [s3 release];
    [s4 release];

    return 0;
}

Концептуально, s1, s2, s3, s4быть разными объектами.Однако, запустив эту программу, вы можете видеть, что это фактически один и тот же объект (они имеют одинаковый адрес):

$ ./a.out
s1 = 0x10080b090
s2 = 0x10080b090
s3 = 0x10080b090
s4 = 0x10080b090
2 голосов
/ 12 сентября 2011

Это неопределенное поведение.У вас нет доступа к этой строке, но она может быть доступна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...