class_createInstance函数源码

/***********************************************************************

  • class_createInstance

  • fixme

  • Locking: none
    **********************************************************************/


    static attribute((always_inline))
    id
    _class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone)
    {
    if (!cls) return nil;
    assert(cls->isRealized());

    // Read class's info bits all at once for performance
    bool hasCxxCtor = cls->hasCxxCtor();
    bool hasCxxDtor = cls->hasCxxDtor();
    bool fast = cls->canAllocIndexed();

    size_t size = cls->instanceSize(extraBytes);

    id obj;
    if (!UseGC && !zone && fast) {
    obj = (id)calloc(1, size);
    if (!obj) return nil;
    obj->initInstanceIsa(cls, hasCxxDtor);
    }
    else {

if SUPPORT_GC

    if (UseGC) {
        obj = (id)auto_zone_allocate_object(gc_zone, size,
                                            AUTO_OBJECT_SCANNED, 0, 1);
    } else 

endif

    if (zone) {
        obj = (id)malloc_zone_calloc ((malloc_zone_t *)zone, 1, size);
} else {
        obj = (id)calloc(1, size);
    }
    if (!obj) return nil;

    // Use non-indexed isa on the assumption that they might be 
    // doing something weird with the zone or RR.
    obj->initIsa(cls);
}

if (hasCxxCtor) {
    obj = _objc_constructOrFree(obj, cls);
}

return obj;

}
id
class_createInstance(Class cls, size_t extraBytes)
{
return _class_createInstanceFromZone(cls, extraBytes, nil);
}

/***********************************************************************

  • class_createInstances
  • fixme
  • Locking: none
    **********************************************************************/

if SUPPORT_NONPOINTER_ISA

warning fixme optimize class_createInstances

endif

unsigned
class_createInstances(Class cls, size_t extraBytes,
id *results, unsigned num_requested)
{
return _class_createInstancesFromZone(cls, extraBytes, nil,
results, num_requested);
}
static BOOL classOrSuperClassesUseARR(Class cls) {
while (cls) {
if (_class_usesAutomaticRetainRelease(cls)) return true;
cls = cls->superclass;
}
return false;
}
static void arr_fixup_copied_references(id newObject, id oldObject)
{
// use ARR layouts to correctly copy the references from old object to new, both strong and weak.
Class cls = oldObject->ISA();
for ( ; cls; cls = cls->superclass) {
if (_class_usesAutomaticRetainRelease(cls)) {
// FIXME: align the instance start to nearest id boundary. This currently handles the case where
// the the compiler folds a leading BOOL (char, short, etc.) into the alignment slop of a superclass.
size_t instanceStart = _class_getInstanceStart(cls);
const uint8_t *strongLayout = class_getIvarLayout(cls);
if (strongLayout) {
id *newPtr = (id )((char)newObject + instanceStart);
unsigned char byte;
while ((byte = *strongLayout++)) {
unsigned skips = (byte >> 4);
unsigned scans = (byte & 0x0F);
newPtr += skips;
while (scans--) {
// ensure strong references are properly retained.
id value = *newPtr++;
if (value) objc_retain(value);
}
}
}
const uint8_t *weakLayout = class_getWeakIvarLayout(cls);
// fix up weak references if any.
if (weakLayout) {
id *newPtr = (id )((char)newObject + instanceStart), *oldPtr = (id )((char)oldObject + instanceStart);
unsigned char byte;
while ((byte = *weakLayout++)) {
unsigned skips = (byte >> 4);
unsigned weaks = (byte & 0x0F);
newPtr += skips, oldPtr += skips;
while (weaks--) {
*newPtr = nil;
objc_storeWeak(newPtr, objc_loadWeak(oldPtr));
++newPtr, ++oldPtr;
}
}
}
}
}
}

你可能感兴趣的:(class_createInstance函数源码)