2011-12-19 5 views
1

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

[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 

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

ответ

5

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

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

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

self.obj = nil; 

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

+0

Спасибо человеку. Делает смысл –

+0

Это верно, если неатомный атрибут не установлен в свойстве obj. http://developer.apple.com/library/mac/# documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html – Joel

+0

Да, я понимаю. Посмотрите ниже на мой комментарий @DBD. Я сделал свойства не атомными. Спасибо tho :) –

1

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

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

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

+1

Хороший вопрос. Спасибо, но я пошел с настройкой его свойства как атомного, как указано ниже. –

+0

Отправка 'release' на результат вызова доступа не является лучшей идеей. Смотрите: http://stackoverflow.com/questions/7262268/why-shouldnt-i-use-the-getter-to-release-a-property-in-objective-c –

4

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

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

используется self.obj означает, что вы ссылаетесь методы аксессоры/Мутаторы вместо доступа вашего объекта непосредственно. Скорее всего, вы объявляете «obj» как сохраненное свойство. Ваш .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; 

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

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

+0

Спасибо, у меня есть выбранная комбинация и ответ Андерса выше. Я буду использовать ** self.obj = nil; **, который вызовет установщик, чтобы выпустить старое значение. Кроме того, я буду устанавливать @property как атомный, как вы сказали. Я выбрал его ответ ... можно выбрать только один правильный ответ>< –

Смежные вопросы