iosswiftparse-platformsubclasspfobject

To-one relationship to PFObject subclass fails with circular reference


I'm creating two custom PFObject subclass: Match and Set A match has a property called setTest which point to a Set. Both class are registered with Parse in the app delegate. When I initialize a match object (which creates a set object too), i get an exception.

What am I doing wrong?

Thanks!

Match class:

class Match: PFObject, PFSubclassing
{
    @NSManaged var setTest:Set?


    convenience init (defaults:String?)
    {
        self.init()
        self.setTest = Set(withPlayer1Score: 0, player2Score: 0)
    }
}

static func parseClassName() -> String
{
    return "Match"
}

Set class:

class Set: PFObject, PFSubclassing {
    @NSManaged var player1Score:NSNumber?
    @NSManaged var player2Score:NSNumber?

    convenience init(withPlayer1Score player1Score:Int, player2Score:Int) {
        self.init()

        self.player1Score = player1Score
        self.player2Score = player2Score
    }



    //MARK: PFSubclassing
    static func parseClassName() -> String
    {
        return "Set"
    }
}

Then somewhere in code i call

let match = Match(defaults: nil)
match.startDate = NSDate()
match.saveInBackgroundWithBlock({ (completed:Bool, error:NSError?) -> Void in
    assert(completed)
})

When saveInBackground() runs, I get the following exception:

2015-12-31 14:41:18.337 TenStats Debug[4055:2031064] [Error]: Caught "NSInternalInconsistencyException" with reason "Found a circular dependency when saving.":
(
0   CoreFoundation                      0x0000000184b7d918 <redacted> + 148
1   libobjc.A.dylib                     0x00000001841ebf80 objc_exception_throw + 56
2   CoreFoundation                      0x0000000184b7d848 <redacted> + 0
3   Parse                               0x00000001007a53a4 +[PFObject(Private) collectDirtyChildren:children:files:seen:seenNew:currentUser:] + 1660
4   Parse                               0x00000001007a5788 __82+[PFObject(Private) collectDirtyChildren:children:files:seen:seenNew:currentUser:]_block_invoke + 136
5   CoreFoundation                      0x0000000184aceed4 <redacted> + 88
6   CoreFoundation                      0x0000000184abcb78 <redacted> + 224
7   Parse                               0x00000001007a50e8 +[PFObject(Private) collectDirtyChildren:children:files:seen:seenNew:currentUser:] + 960
8   Parse                               0x00000001007a551c +[PFObject(Private) collectDirtyChildren:children:files:seen:seenNew:currentUser:] + 2036
9   Parse                               0x00000001007a5a74 +[PFObject(Private) collectDirtyChildren:children:files:currentUser:] + 308
10  Parse                               0x00000001007a6694 +[PFObject(Private) _deepSaveAsyncChildrenOfObject:withCurrentUser:sessionToken:] + 260
11  Parse                               0x00000001007aa094 -[PFObject(Private) _saveChildrenInBackgroundWithCurrentUser:sessionToken:] + 176
12  Parse                               0x00000001007b2ddc __31-[PFObject(Private) saveAsync:]_block_invoke581 + 368
13  Bolts                               0x000000010055c2f4 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_2 + 124
14  Bolts                               0x00000001005586b8 __29+[BFExecutor defaultExecutor]_block_invoke_2 + 168
15  Bolts                               0x00000001005590f4 -[BFExecutor execute:] + 108
16  Bolts                               0x000000010055c21c __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke + 228
17  Bolts                               0x000000010055bc4c -[BFTask runContinuations] + 568
18  Bolts                               0x000000010055b224 -[BFTask trySetResult:] + 248
19  Bolts                               0x000000010055dc4c -[BFTaskCompletionSource setResult:] + 108
20  Bolts                               0x000000010055c79c __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_3 + 528
21  Bolts                               0x000000010055c2f4 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_2 + 124
22  Bolts                               0x00000001005586b8 __29+[BFExecutor defaultExecutor]_block_invoke_2 + 168
23  Bolts                               0x00000001005590f4 -[BFExecutor execute:] + 108
24  Bolts                               0x000000010055c21c __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke + 228
25  Bolts                               0x000000010055bc4c -[BFTask runContinuations] + 568
26  Bolts                               0x000000010055b224 -[BFTask trySetResult:] + 248
27  Bolts                               0x000000010055dc4c -[BFTaskCompletionSource setResult:] + 108
28  Bolts                               0x000000010055c79c __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_3 + 528
29  Bolts                               0x000000010055c430 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_2 + 440
30  Bolts                               0x00000001005586b8 __29+[BFExecutor defaultExecutor]_block_invoke_2 + 168
31  Bolts                               0x00000001005590f4 -[BFExecutor execute:] + 108
32  Bolts                               0x000000010055c21c __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke + 228
33  Bolts                               0x000000010055bc4c -[BFTask runContinuations] + 568
34  Bolts                               0x000000010055b224 -[BFTask trySetResult:] + 248
35  Bolts                               0x000000010055dc4c -[BFTaskCompletionSource setResult:] + 108
36  Bolts                               0x000000010055c79c __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_3 + 528
37  Bolts                               0x000000010055c2f4 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_2 + 124
38  Bolts                               0x00000001005586b8 __29+[BFExecutor defaultExecutor]_block_invoke_2 + 168
39  Bolts                               0x00000001005590f4 -[BFExecutor execute:] + 108
40  Bolts                               0x000000010055c21c __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke + 228
41  Bolts                               0x000000010055bc4c -[BFTask runContinuations] + 568
42  Bolts                               0x000000010055b224 -[BFTask trySetResult:] + 248
43  Bolts                               0x000000010055dc4c -[BFTaskCompletionSource setResult:] + 108
44  Bolts                               0x000000010055c79c __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_3 + 528
45  Bolts                               0x000000010055c2f4 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_2 + 124
46  Bolts                               0x00000001005586b8 __29+[BFExecutor defaultExecutor]_block_invoke_2 + 168
47  Bolts                               0x00000001005590f4 -[BFExecutor execute:] + 108
48  Bolts                               0x000000010055c21c __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke + 228
49  Bolts                               0x000000010055bc4c -[BFTask runContinuations] + 568
50  Bolts                               0x000000010055b224 -[BFTask trySetResult:] + 248
51  Bolts                               0x000000010055dc4c -[BFTaskCompletionSource setResult:] + 108
52  Bolts                               0x000000010055c79c __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_3 + 528
53  Bolts                               0x000000010055c430 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_2 + 440
54  libdispatch.dylib                   0x0000000101c95bb0 _dispatch_client_callout + 16
55  libdispatch.dylib                   0x0000000101ca1764 _dispatch_barrier_sync_f_invoke + 164
56  Parse                               0x0000000100832dc0 PFThreadsafetySafeDispatchSync + 168
57  Parse                               0x000000010082b210 __33-[PFSQLiteDatabase initWithPath:]_block_invoke_2 + 40
58  libdispatch.dylib                   0x0000000101c95bf0 _dispatch_call_block_and_release + 24
59  libdispatch.dylib                   0x0000000101c95bb0 _dispatch_client_callout + 16
60  libdispatch.dylib                   0x0000000101ca4e10 _dispatch_root_queue_drain + 2344
61  libdispatch.dylib                   0x0000000101ca44d8 _dispatch_worker_thread3 + 132
62  libsystem_pthread.dylib             0x00000001847e5470 _pthread_wqthread + 1092
63  libsystem_pthread.dylib             0x00000001847e5020 start_wqthread + 4
).

Solution

  • You can't set an object as the destination of a pointer or add it to a relationship until it has been saved. The exception you see isn't a very good explanation of that but you will need to save the Set before you connect it to the Match.