Repository: realm/realm-swift
File: Realm/RLMObjectStore.mm (Objective-C++)

Code before:
    if (!realm.inWriteTransaction) {
        @throw [NSException exceptionWithName:@"RLMException"
                                       reason:@"Can only add an object to a Realm in a write transaction - call beginWriteTransaction on a RLMRealm instance first."
                                     userInfo:nil];
    }
}

void RLMAddObjectToRealm(RLMObject *object, RLMRealm *realm) {
    // if already in the right realm then no-op
    if (object.realm == realm) {
        return;
    }

    // verify writable
    RLMVerifyInWriteTransaction(realm);
    
    // set the realm and schema
    NSString *objectClassName = [object.class className];
    RLMObjectSchema *schema = realm.schema[objectClassName];
    object.objectSchema = schema;
    object.realm = realm;

    // create row in table
    tightdb::TableRef &table = schema->_table;
    size_t rowIndex = table->add_empty_row();
    object->_row = (*table)[rowIndex];

    // populate all properties
    for (RLMProperty *prop in schema.properties) {
        // get object from ivar using key value coding
        id value = nil;
        if ([object respondsToSelector:NSSelectorFromString(prop.name)]) {
            value = [object valueForKey:prop.name];
        }

        // FIXME: Add condition to check for Mixed once it can support a nil value.
        if (!value && prop.type != RLMPropertyTypeObject) {
            @throw [NSException exceptionWithName:@"RLMException"
                                           reason:[NSString stringWithFormat:@"No value or default value specified for %@ property", prop.name]
                                         userInfo:nil];
        }

        // set in table with out validation
        RLMDynamicSet(object, prop, value);
    }

    // switch class to use table backed accessor
    object_setClass(object, schema.accessorClass);
}



Review comment (performance):
In a case like the one above, there was no copying of the `TableRef` (due to the `&`), but the updated version is still more optimizer friendly, because it effectively copies the pointer, rather than a "pointer to the pointer".


Code after:
    if (!realm.inWriteTransaction) {
        @throw [NSException exceptionWithName:@"RLMException"
                                       reason:@"Can only add an object to a Realm in a write transaction - call beginWriteTransaction on a RLMRealm instance first."
                                     userInfo:nil];
    }
}

void RLMAddObjectToRealm(RLMObject *object, RLMRealm *realm) {
    // if already in the right realm then no-op
    if (object.realm == realm) {
        return;
    }

    // verify writable
    RLMVerifyInWriteTransaction(realm);
    
    // set the realm and schema
    NSString *objectClassName = [object.class className];
    RLMObjectSchema *schema = realm.schema[objectClassName];
    object.objectSchema = schema;
    object.realm = realm;

    // create row in table
    tightdb::Table &table = *schema->_table;
    size_t rowIndex = table.add_empty_row();
    object->_row = table[rowIndex];

    // populate all properties
    for (RLMProperty *prop in schema.properties) {
        // get object from ivar using key value coding
        id value = nil;
        if ([object respondsToSelector:NSSelectorFromString(prop.name)]) {
            value = [object valueForKey:prop.name];
        }

        // FIXME: Add condition to check for Mixed once it can support a nil value.
        if (!value && prop.type != RLMPropertyTypeObject) {
            @throw [NSException exceptionWithName:@"RLMException"
                                           reason:[NSString stringWithFormat:@"No value or default value specified for %@ property", prop.name]
                                         userInfo:nil];
        }

        // set in table with out validation
        RLMDynamicSet(object, prop, value);
    }

    // switch class to use table backed accessor
    object_setClass(object, schema.accessorClass);
}