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

Code before:

- (void)dealloc
{
    [_updateTimer invalidate];
    _updateTimer = nil;
    
    if (self.transactionMode == RLMTransactionModeWrite) {
        [self commitWriteTransaction];
    }
    [self endReadTransaction];
}

- (void)refresh {
    try {
        // no-op if writing
        if (self.transactionMode == RLMTransactionModeWrite) {
            return;
        }
        
        // advance transaction if database has changed
        if (_sharedGroup->has_changed()) { // Throws
            [self endReadTransaction];
            [self beginReadTransaction];
            [self updateAllObjects];
            
            // send notification that someone else changed the realm
            [self sendNotifications];
        }
    }
    catch (exception &ex) {
        throw_objc_exception(ex);
    }
}

- (void)registerAccessor:(id<RLMAccessor>)accessor {
    [_objects setObject:accessor forKey:accessor];
}

- (void)updateAllObjects {
    try {
        // get the group
        tightdb::Group *group = self.group;
        BOOL writable = (self.transactionMode == RLMTransactionModeWrite);

        // refresh all outstanding objects
        for (id<RLMAccessor> obj in _objects.objectEnumerator.allObjects) {
            TableRef tableRef = group->get_table(obj.backingTableIndex); // Throws
            obj.backingTable = tableRef.get();
            obj.writable = writable;
        }
    }

Review comment (suggestion):
Throwing an exception during object destruction isn't really an option, as much of the time this happens at the end of an autoreleasepool. The only good solution will be to support implicit writes or to only support transaction blocks. 

> On May 20, 2014, at 3:14 PM, bmunkholm notifications@github.com wrote:
> 
> In Realm/RLMRealm.mm:
> 
> > @@ -391,7 +397,9 @@ - (void)dealloc
> >      [_updateTimer invalidate];
> >      _updateTimer = nil;
> > -    [self commitWriteTransaction];
> > -    if (self.transactionMode == RLMTransactionModeWrite) {
> >   Moving towards implicit write this will hopefully not be an issue. But guessing what the user has forgotten is likely not the correct thing to do here. Maybe an exception would be more appropriate - so his code can get fixed?
> >   …
> >   —
> >   Reply to this email directly or view it on GitHub.


Code after:
       @throw [NSException exceptionWithName:@"RLMException" reason:@"Can't commit a non-existing writetransaction" userInfo:nil];
    }
}

- (void)rollbackWriteTransaction {
    if (self.transactionMode == RLMTransactionModeWrite) {
        try {
            _sharedGroup->rollback();
            _writeGroup = NULL;
            
            [self beginReadTransaction];
        }
        catch (std::exception& ex) {
            throw_objc_exception(ex);
        }
    } else {
        @throw [NSException exceptionWithName:@"RLMException" reason:@"Can't roll-back a non-existing writetransaction" userInfo:nil];
    }
}

- (void)dealloc
{
    [_updateTimer invalidate];
    _updateTimer = nil;
    
    if (self.transactionMode == RLMTransactionModeWrite) {
        [self commitWriteTransaction];
    }
    [self endReadTransaction];
}

- (void)refresh {
    try {
        // no-op if writing
        if (self.transactionMode == RLMTransactionModeWrite) {
            return;
        }
        
        // advance transaction if database has changed
        if (_sharedGroup->has_changed()) { // Throws
            [self endReadTransaction];
            [self beginReadTransaction];
            [self updateAllObjects];
            
            // send notification that someone else changed the realm
            [self sendNotifications];
        }
    }
    catch (exception &ex) {
        throw_objc_exception(ex);
    }