Skip to content

Commit 77e59ff

Browse files
committed
Fixed #7 - Keep WeakReference to parent ParseObject in ParseRelation
As suggested in the issue, keeping reference to parent objectId, className and recreating parent pointer when the parent is GC'ed. All tests passed locally.
1 parent 08b1f23 commit 77e59ff

File tree

1 file changed

+30
-9
lines changed

1 file changed

+30
-9
lines changed

Parse/src/main/java/com/parse/ParseRelation.java

+30-9
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99
package com.parse;
1010

11+
import java.lang.ref.WeakReference;
1112
import java.util.Collections;
1213
import java.util.HashSet;
1314
import java.util.Set;
@@ -24,7 +25,13 @@ public class ParseRelation<T extends ParseObject> {
2425
private final Object mutex = new Object();
2526

2627
// The owning object of this ParseRelation.
27-
private ParseObject parent;
28+
private WeakReference<ParseObject> parent;
29+
30+
// The object Id of the parent.
31+
private String parentObjectId;
32+
33+
// The classname of the parent to retrieve the parent ParseObject in case the parent is GC'ed.
34+
private String parentClassName;
2835

2936
// The key of the relation in the parent object.
3037
private String key;
@@ -36,13 +43,17 @@ public class ParseRelation<T extends ParseObject> {
3643
private Set<ParseObject> knownObjects = new HashSet<>();
3744

3845
/* package */ ParseRelation(ParseObject parent, String key) {
39-
this.parent = parent;
46+
this.parent = new WeakReference<>(parent);
47+
this.parentObjectId = parent.getObjectId();
48+
this.parentClassName = parent.getClassName();
4049
this.key = key;
4150
this.targetClass = null;
4251
}
4352

4453
/* package */ ParseRelation(String targetClass) {
4554
this.parent = null;
55+
this.parentObjectId = null;
56+
this.parentClassName = null;
4657
this.key = null;
4758
this.targetClass = targetClass;
4859
}
@@ -52,6 +63,8 @@ public class ParseRelation<T extends ParseObject> {
5263
*/
5364
/* package */ ParseRelation(JSONObject jsonObject, ParseDecoder decoder) {
5465
this.parent = null;
66+
this.parentObjectId = null;
67+
this.parentClassName = null;
5568
this.key = null;
5669
this.targetClass = jsonObject.optString("className", null);
5770
JSONArray objectsArray = jsonObject.optJSONArray("objects");
@@ -65,12 +78,14 @@ public class ParseRelation<T extends ParseObject> {
6578
/* package */ void ensureParentAndKey(ParseObject someParent, String someKey) {
6679
synchronized (mutex) {
6780
if (parent == null) {
68-
parent = someParent;
81+
parent = new WeakReference<>(someParent);
82+
parentObjectId = someParent.getObjectId();
83+
parentClassName = someParent.getClassName();
6984
}
7085
if (key == null) {
7186
key = someKey;
7287
}
73-
if (parent != someParent) {
88+
if (parent.get() != someParent) {
7489
throw new IllegalStateException(
7590
"Internal error. One ParseRelation retrieved from two different ParseObjects.");
7691
}
@@ -92,7 +107,7 @@ public void add(T object) {
92107
ParseRelationOperation<T> operation =
93108
new ParseRelationOperation<>(Collections.singleton(object), null);
94109
targetClass = operation.getTargetClass();
95-
parent.performOperation(key, operation);
110+
getParent().performOperation(key, operation);
96111

97112
knownObjects.add(object);
98113
}
@@ -109,7 +124,7 @@ public void remove(T object) {
109124
ParseRelationOperation<T> operation =
110125
new ParseRelationOperation<>(null, Collections.singleton(object));
111126
targetClass = operation.getTargetClass();
112-
parent.performOperation(key, operation);
127+
getParent().performOperation(key, operation);
113128

114129
knownObjects.remove(object);
115130
}
@@ -124,12 +139,12 @@ public ParseQuery<T> getQuery() {
124139
synchronized (mutex) {
125140
ParseQuery.State.Builder<T> builder;
126141
if (targetClass == null) {
127-
builder = new ParseQuery.State.Builder<T>(parent.getClassName())
142+
builder = new ParseQuery.State.Builder<T>(parentClassName)
128143
.redirectClassNameForKey(key);
129144
} else {
130145
builder = new ParseQuery.State.Builder<>(targetClass);
131146
}
132-
builder.whereRelatedTo(parent, key);
147+
builder.whereRelatedTo(getParent(), key);
133148
return new ParseQuery<>(builder);
134149
}
135150
}
@@ -193,7 +208,13 @@ public ParseQuery<T> getQuery() {
193208
}
194209

195210
/* package for tests */ ParseObject getParent() {
196-
return parent;
211+
if(parent == null){
212+
return null;
213+
}
214+
if(parent.get() == null){
215+
return ParseDecoder.get().decodePointer(parentClassName, parentObjectId);
216+
}
217+
return parent.get();
197218
}
198219

199220
/* package for tests */ String getKey() {

0 commit comments

Comments
 (0)