2015-06-05 2 views
3

Безопасно ли читать неатомный слабый указатель из другого потока, чем объект освобождается?Безопасно ли читать слабый указатель во время его освобождения?

В общем, я знаю, что свойства должны быть сделаны атомами, когда могут быть одновременные обращения, по крайней мере одна из которых является операцией записи. Но я должен задаться вопросом, является ли операция записи ARC (установка указателя на нуль) как-то особенной. В противном случае я ожидал увидеть больше предупреждений об этой возможной проблеме. Возможно, слабые указатели неявно атомарны?

ответ

3

Это безопасно. Доступ к слабому указателю и слабому указателю Zeroing находится между spinlock_lock и spinlock_unlock.

Посмотрите на исходном коде во время выполнения http://opensource.apple.com/source/objc4/objc4-646/runtime/NSObject.mm

Доступ слабого указатель

id 
objc_loadWeakRetained(id *location) 
{ 
    id result; 

    SideTable *table; 
    spinlock_t *lock; 

retry: 
    result = *location; 
    if (!result) return nil; 

    table = SideTable::tableForPointer(result); 
    lock = &table->slock; 

    spinlock_lock(lock); 
    if (*location != result) { 
     spinlock_unlock(lock); 
     goto retry; 
    } 

    result = weak_read_no_lock(&table->weak_table, location); 

    spinlock_unlock(lock); 
    return result; 
} 

Обнуления слабого указателя

void 
objc_object::sidetable_clearDeallocating() 
{ 
    SideTable *table = SideTable::tableForPointer(this); 

    // clear any weak table items 
    // clear extra retain count and deallocating bit 
    // (fixme warn or abort if extra retain count == 0 ?) 
    spinlock_lock(&table->slock); 
    RefcountMap::iterator it = table->refcnts.find(this); 
    if (it != table->refcnts.end()) { 
     if (it->second & SIDE_TABLE_WEAKLY_REFERENCED) { 
      weak_clear_no_lock(&table->weak_table, (id)this); 
     } 
     table->refcnts.erase(it); 
    } 
    spinlock_unlock(&table->slock); 
} 

И deallocating Объекта поток https://stackoverflow.com/a/14854977/629118

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