简体   繁体   English

非ARC Objective-C属性访问器是什么样的?

[英]What do non-ARC Objective-C property accessors look like?

I want to know how the getter and setter for an Objective-C property are implemented as part of learning the concept of memory management. 我想知道在学习内存管理概念时如何实现Objective-C属性的getter和setter方法。

I have not been able to find an actual representation other than "nonatomic" and "atomic". 除了“非原子”和“原子”以外,我无法找到实际的表示形式。

What does the actual code look like for getters and setters with the different property attributes, such as strong/weak, copy/assign, and __unsafe_unretained? 具有不同属性属性(例如强/弱,复制/赋值和__unsafe_unretained)的getter和setter的实际代码是什么样的?

You can check the source code at the objc4 github repo 您可以在objc4 github repo上检查源代码

getter: https://github.com/opensource-apple/objc4/blob/cd5e62a5597ea7a31dccef089317abb3a661c154/runtime/objc-accessors.mm#L48 吸气剂: https : //github.com/opensource-apple/objc4/blob/cd5e62a5597ea7a31dccef089317abb3a661c154/runtime/objc-accessors.mm#L48

id objc_getProperty_non_gc(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) {
    if (offset == 0) {
        return object_getClass(self);
    }

    // Retain release world
    id *slot = (id*) ((char*)self + offset);
    if (!atomic) return *slot;

    // Atomic retain release world
    spinlock_t& slotlock = PropertyLocks[slot];
    slotlock.lock();
    id value = objc_retain(*slot);
    slotlock.unlock();

    // for performance, we (safely) issue the autorelease OUTSIDE of the spinlock.
    return objc_autoreleaseReturnValue(value);
}

setter: https://github.com/opensource-apple/objc4/blob/cd5e62a5597ea7a31dccef089317abb3a661c154/runtime/objc-accessors.mm#L70 设置器: https : //github.com/opensource-apple/objc4/blob/cd5e62a5597ea7a31dccef089317abb3a661c154/runtime/objc-accessors.mm#L70

static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy)
{
    if (offset == 0) {
        object_setClass(self, newValue);
        return;
    }

    id oldValue;
    id *slot = (id*) ((char*)self + offset);

    if (copy) {
        newValue = [newValue copyWithZone:nil];
    } else if (mutableCopy) {
        newValue = [newValue mutableCopyWithZone:nil];
    } else {
        if (*slot == newValue) return;
        newValue = objc_retain(newValue);
    }

    if (!atomic) {
        oldValue = *slot;
        *slot = newValue;
    } else {
        spinlock_t& slotlock = PropertyLocks[slot];
        slotlock.lock();
        oldValue = *slot;
        *slot = newValue;        
        slotlock.unlock();
    }

    objc_release(oldValue);
}

load weak variable: https://github.com/opensource-apple/objc4/blob/cd5e62a5597ea7a31dccef089317abb3a661c154/runtime/NSObject.mm#L444 加载弱变量: https : //github.com/opensource-apple/objc4/blob/cd5e62a5597ea7a31dccef089317abb3a661c154/runtime/NSObject.mm#L444

id
objc_loadWeakRetained(id *location)
{
    id result;

    SideTable *table;

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

    table = &SideTables()[result];

    table->lock();
    if (*location != result) {
        table->unlock();
        goto retry;
    }

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

    table->unlock();
    return result;
}

I don't think there is any code for unsafe_retained. 我认为unsafe_retained没有任何代码。 Compiler can just simply assign the pointer without anything else. 编译器只需简单地分配指针即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM