Должно ли освобождение объекта и установка его на ноль быть атомарным? - PullRequest
1 голос
/ 20 декабря 2011

Я новичок в Objective C. Во многих приложениях для iPhone / iPad я вижу, что после освобождения объекта ему будет присвоено значение nil.

[self.obj release]
self.obj = nil; 

Я предполагаю, что это сделано так, что нетоставить указатель для ссылки на область памяти, которая теперь освобождена.Теперь предположим следующую ситуацию:

//Thread #1 code
..some code
..some code
[self.obj release]
                  -------> Thread #2 runs //Thread #2 code
                                          ..some code
                                          if (self.obj){
                                            some code
                                          }
self.obj = nil;   <----- Thread #1 runs

Мне было интересно, возможна ли такая ситуация?И если это так, есть ли способ сделать выпуск / ноль атомарным?

Ответы [ 3 ]

5 голосов
/ 20 декабря 2011

это на самом деле не совсем правильно

[self.obj release]
self.obj = nil;

Вы должны написать просто

self.obj = nil;

, который вызовет сеттер, который освободит предыдущий экземпляр.

4 голосов
/ 20 декабря 2011

Да, это может взорваться. Рассмотрим пример кода.

[self.obj release];
self.obj = nil;

Вы используете self.obj, что означает, что вы ссылаетесь на методы accessor / mutators вместо прямого доступа к вашему объекту. Скорее всего, вы бы объявили «объект» в качестве оставшейся собственности. Ваш .h будет что-то вроде ...

@property (retain) Something *obj;

и ваш .m

@synthesize obj;

Если вы позже отпустите свой объект, используя методы, созданные вашим @synthesize, вы в безопасности.

[self setObj:nil];
// or equally valid
self.obj = nil;
// Below is (almost) identical way to access, release and nil the variable directly.
// The major difference is you don't multi-threaded protection of your property
// declaration (explained below).
[obj release];
obj = nil;

Если вы посмотрите на свойство, которое я указал выше, вы заметите, что я не включил в него очень часто встречающееся nonatomic. Это было не случайно. Взгляните на Apple документы

Свойства являются атомарными по умолчанию, так что синтезированные методы доступа обеспечивают надежный доступ к свойствам в многопоточной среде, то есть значение, возвращаемое из метода получения или устанавливаемое через установщик, всегда полностью извлекается или устанавливается независимо от того, какие другие потоки выполняются одновременно .

1 голос
/ 20 декабря 2011

Вы можете заключить обе операции в блок @synchronized, чтобы убедиться, что обе операции завершены до выхода из блока:

@synchronized(lockObject)
{
    [self.obj release];
    self.obj = nil;
}

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

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