Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 读取弱指针时是否安全';什么正在被解除分配?_Objective C_Automatic Ref Counting_Race Condition - Fatal编程技术网

Objective c 读取弱指针时是否安全';什么正在被解除分配?

Objective c 读取弱指针时是否安全';什么正在被解除分配?,objective-c,automatic-ref-counting,race-condition,Objective C,Automatic Ref Counting,Race Condition,从不同的线程读取非原子弱指针是否安全 一般来说,我知道属性应该是原子的,只要有可能同时访问,其中至少有一个是写操作。但我不得不怀疑ARC的写操作(将指针设置为nil)是否有特殊之处。否则,我会期望看到更多关于这个可能问题的警告。也许弱指针是隐式原子的?这是安全的。访问弱指针和归零弱指针位于spinlock_lock和spinlock_unlock之间 请看一下运行时源代码 访问弱指针 id objc_loadWeakRetained(id *location) { id result;

从不同的线程读取非原子弱指针是否安全


一般来说,我知道属性应该是原子的,只要有可能同时访问,其中至少有一个是写操作。但我不得不怀疑ARC的写操作(将指针设置为nil)是否有特殊之处。否则,我会期望看到更多关于这个可能问题的警告。也许弱指针是隐式原子的?

这是安全的。访问弱指针和归零弱指针位于spinlock_lock和spinlock_unlock之间

请看一下运行时源代码

访问弱指针

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);
}
调零弱指针

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);
}
以及对象释放流