From a3f63880da6894260f51f78c3aea4566c3a0c35a Mon Sep 17 00:00:00 2001 From: Pasin Suriyentrakorn Date: Mon, 13 Apr 2015 14:58:36 -0700 Subject: [PATCH] Fix circular reference between CBLUnsavedRevision and CBLAttachment - As CBLUnsavedRevision keeps CBLAttachment objects in an array so setting the revision (self) object to the CBLAttachment objects will cause circular reference memory leak. - Instead of setting the revision (self) object when adding a CBLAttachment to the CBLUnsavedRevision object, overiding the attachmentNamed: method and creating a new CBLAttachment object and adding a revision object there. --- Source/API/CBLAttachment.m | 2 +- Source/API/CBLRevision.m | 18 +++++++++++++++++- Source/API/CouchbaseLitePrivate.h | 1 + 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Source/API/CBLAttachment.m b/Source/API/CBLAttachment.m index 0fd1a8594..9a7043b25 100644 --- a/Source/API/CBLAttachment.m +++ b/Source/API/CBLAttachment.m @@ -72,7 +72,7 @@ - (instancetype) _initWithContentType: (NSString*)contentType } -@synthesize revision=_rev, name=_name, metadata=_metadata; +@synthesize revision=_rev, name=_name, body = _body, metadata=_metadata; - (NSString *)description diff --git a/Source/API/CBLRevision.m b/Source/API/CBLRevision.m index ecc79cf6e..c0f90fed5 100644 --- a/Source/API/CBLRevision.m +++ b/Source/API/CBLRevision.m @@ -367,12 +367,28 @@ - (void) _addAttachment: (CBLAttachment*)attachment named: (NSString*)name { [atts setValue: attachment forKey: name]; _properties[@"_attachments"] = atts; attachment.name = name; - attachment.revision = self; + + // NOTE: Not setting the revision to the attachment object (attachment.revision = self) as + // [1] The UnsavedRevision object is not used during save operation + // [2] Setting the UnsavedRevision object here will cause the circular reference memory leak. + // The revision object will be set in the overridden attachmentName: method. } - (void) removeAttachmentNamed: (NSString*)name { [self _addAttachment: nil named: name]; } +- (CBLAttachment*) attachmentNamed: (NSString*)name { + CBLAttachment* base = self.attachmentMetadata[name]; + if (base) { + CBLAttachment* attachment = [[CBLAttachment alloc] _initWithContentType: base.contentType + body: base.body]; + attachment.name = name; + attachment.revision = self; + return attachment; + } + return nil; +} + @end diff --git a/Source/API/CouchbaseLitePrivate.h b/Source/API/CouchbaseLitePrivate.h index 859402992..6e0b6843e 100644 --- a/Source/API/CouchbaseLitePrivate.h +++ b/Source/API/CouchbaseLitePrivate.h @@ -116,6 +116,7 @@ intoDatabase: (CBLDatabase*)database __attribute__((nonnull(2))); @property (readwrite, copy) NSString* name; @property (readwrite, retain) CBLRevision* revision; +@property (readonly) id body; @end