New CBLModel object being created by following the relationship

24 views
Skip to first unread message

Brendan Duddridge

unread,
Mar 27, 2016, 2:52:44 PM3/27/16
to Couchbase Mobile
Hi,

I have a relationship between two of my model objects. TFField has a pickList property:

TFField -> TFPickList

With an inverse one-to-many relationship called fields between TFPickList and TFField:

TFPickList ->> TFField

When I am deallocating an instance of one of my GUI classes, I do a check to see what kind of TFPickList object I'm dealing with and then I do some additional stuff before dealloc finishes. What I've found is simply by traversing the relationship to determine if a pickList object exists on the TFField object, a new TFPickList instance is being created for me. It's not what I was expecting.

My dealloc is simply:

- (void)dealloc {

       if (self.field.pickList.isPopupButton) {

               [self.currentCellView.popupButton unbind:@"selectedValue"];

               [self.currentCellView.popupButton unbind:@"content"];

               [self.currentCellView.popupButton unbind:@"contentValues"];

       }

}


As soon as self.field.pickList.isPopupButton is called, CBL tries to create a TFPickList object:

#0 0x00000001003c7496 in -[TFPickList awakeFromInitializer] at TFPickList.m:38
#1 0x0000000100c93861 in -[CBLModel initWithDocument:orDatabase:] at CBLModel.m:52
#2 0x0000000100c93d4b in +[CBLModel modelForDocument:] at CBLModel.m:86
#3 0x0000000100c96836 in -[CBLModel modelWithDocID:forProperty:ofClass:] at CBLModel.m:540
#4 0x0000000100ca0853 in -[CBLModel(Properties) getModelProperty:] at CBLModel+Properties.m:120
#5 0x00000001004074c9 in -[TextCellController dealloc] at TextCellController.m:329



And then the TFPickList instance gets deallocated, but with unsaved properties:

TFPickList[pik-..f47a] deallocated with unsaved changes.

2016-03-27 12:44:01.499 Tap Forms[52964:1215713] properties to save: {

    "_id" = "pik-439f938ddaf845568ee2b853493cf47a";

    displayAs = single;

    name = "New Pick List";

}


I have an inverse relationship defined on my TFPickList class and TFField as follows:

+ (Class)fieldsItemClass { return [TFField class]; }

+ (NSString *)fieldsInverseRelation { return @"pickList"; }


So I'm just wondering if it's normal behaviour for an object in a  relationship to get created simply by following the path to that relationship? I would think that it shouldn't automatically be created.

What could be causing this and is there something I should do about it? Or should I just ignore it since the unneeded instance is getting deallocated anyway. 

Seems like a bug to me though. Either that or I'm doing something wrong.

Thanks,

Brendan

Jens Alfke

unread,
Mar 28, 2016, 10:45:29 AM3/28/16
to mobile-c...@googlegroups.com

> On Mar 27, 2016, at 2:52 PM, Brendan Duddridge <bren...@gmail.com> wrote:
>
> So I'm just wondering if it's normal behaviour for an object in a relationship to get created simply by following the path to that relationship? I would think that it shouldn't automatically be created.

The relationship is stored as a JSON property whose value is the target object’s docID. So if the property exists, accessing the property will instantiate the target model object, as shown in the backtrace. But if the property doesn’t exist, the property getter will just return nil. You can look at the implementation of -[CBLModel getModelProperty:]; it’s pretty straightforward.

> And then the TFPickList instance gets deallocated, but with unsaved properties:


Hm, that shouldn’t happen. But why is the TFPickList instance getting changed, when it looks like you’re just getting its isPopUpButton property? That seems wrong. Are you changing properties in its -awakeFromInitializer method?

—Jens

Brendan Duddridge

unread,
Mar 28, 2016, 1:53:39 PM3/28/16
to Couchbase Mobile
I'm just setting the properties to their default values in awakeFromInitializer, but only if it's a new object.

- (void)awakeFromInitializer {

       [super awakeFromInitializer];

       if (self.isNew) {

               self.name = NSLocalizedString(@"New Pick List", @"");

               self.displayAs = kTFSingleSelect;

       }

}


There should be no target object ID in this instance though and awakeFromInitializer is getting called only at the moment I'm checking the isPopupButton property.

Jens Alfke

unread,
Mar 29, 2016, 12:41:41 PM3/29/16
to mobile-c...@googlegroups.com

On Mar 28, 2016, at 1:53 PM, Brendan Duddridge <bren...@gmail.com> wrote:

There should be no target object ID in this instance though and awakeFromInitializer is getting called only at the moment I'm checking the isPopupButton property.

I’d set a breakpoint in that dealloc method and inspect the properties of the document. It seems like they’re not what you expect and there is a property linking to the other model object.

—Jens
Reply all
Reply to author
Forward
0 new messages