Код для неатомарного удерживающего геттера и сеттера концептуально выглядит примерно так:
-(id) foo
{
return fooIvar;
}
-(void) setFoo: (id) newFoo
{
[newFoo retain];
[fooIvar release];
fooIvar = newFoo;
}
Код для атомарного геттера и сеттера концептуально выглядит примерно так:
-(id) foo
{
@synchronized(self)
{
return [[fooIvar retain] autorelease];
}
}
-(void) setFoo: (id) newFoo
{
@synchronized(self)
{
[newFoo retain];
[fooIvar release];
fooIvar = newFoo;
}
}
Детали реализации отличаются, в частности, блокировка более легкая, чем синхронизация объекта с помощью ivar.
В неатомарном случае и в многопоточной среде вы не можете гарантировать, что получатель даст вам действительныйобъект, потому что между получателем, возвращающим ссылку, и вызывающим, сохраняющим ее (или делающим что-либо еще), другой поток может вызвать установщик, освобождая объект и, возможно, освобождая его.потому что получатель помещает объект в пул автоматического выпуска потока перед его возвратом.Если другой поток вызывает сеттер и освобождает объект до того, как вызывающая сторона сможет его сохранить, это не имеет значения из-за владения пулом автоматического выпуска.