Skip to content
This repository has been archived by the owner on Jun 13, 2023. It is now read-only.

app crash at with message message sent to deallocated instance . #214

Open
ahsanghauri opened this issue Oct 9, 2019 · 4 comments
Open
Labels

Comments

@ahsanghauri
Copy link

fileprivate func subscriptionRecord(_ requestId: RequestId) -> SubscriptionRecord? {
    guard
        let recordIndex = self.subscriptions.index(where: { $0.requestId == requestId }) else {
            return nil
    }
    let record = self.subscriptions[recordIndex]
    return record.subscriptionHandler != nil ? record : nil
}

app crash at return statement.

@noobs2ninjas
Copy link
Member

So if I'm understanding this the the subscription handler is deallocating?

I think we are also missing some context as to how this is implemented. There are probably a half dozen ways to set PLQ up.

@ritteraf
Copy link

Hi @noobs2ninjas I'm running into the same issue. It looks like @ahsanghauri solved his problem, without ever posting his solution... grrrr....

I can give more context to my situation here:
I am using ParseLiveQuery in conjunction with pinning to fetch and store new messages in a chat style app. The logic is as follows:

  1. A MessageThread() (chat room) object is created by a user.
  2. The live query subscription detects the new object, and displays it to both users. Both users pin the object with name "MessageThread".
  3. One of the users sends a message by creating a Message() object, which is pointed to by updating the MessageThread() with a new pointer to this object.
  4. The live query detects the update in the Event.updated handler
  5. I do a full data fetch on the MessgeThread() object, including the pointer to the "newMessage"
  6. Since the MessageThread() is already pinned, that object should automatically update from the full data fetch.
  7. The new Message() is pinned with the name "Message" to create a separate stored instance of the object - so that the object is not lost on the next update to the "MessageThread", which will no longer contain the previous Message object.
  8. The view controller is notified via NotificationCenter that a new message has been created on the thread.
  9. The view controller fetches the message object from the pin "Message", and displays it (NOT from the MessageThread() pointer!). All seems to be going well. The live query detected the update with the new message, and displayed it as expected.
    HERE IS WHERE IT HAPPENS. Before taking the next action, I view the saved objects in my Parse browser to make sure that the previous Message() and MessageThread() were correctly saved. They are, and all looks good
  10. Either user attempts to send a SECOND message by creating a new Message() object, and updating the pointer on the MessageThread() to point to the new message. I attempt to save the Message() object, and I crash with a EXC_BAD_ACCESS memory error.

I am able to get the following error message by enabling the "object zombie" thing in the scheme for objective-C (which I have no idea what that is)

2020-05-21 10:26:00.837072-0500 SwagLeagues[2506:1000754] *** -[SwagLeagues.Message retain]: message sent to deallocated instance 0x176964420

At this point, the Message() object is not saved, nor is the MessageThread() object updated. If I comment out the code to not update the MessageThread() (which triggers the live query update), then the message successfully saves to the server, but is obviously not displayed, as that is processed by the LiveQuery.

I've spent 8 plus hours troubleshooting this, stripping down all the extra code down to bare bones in an attempt to pin down what's going on. The best reason for the crash that I can give you is it that I think it has something to do with having that Message() object pinned twice. Once as a pointer from the MessageThread(), and the second as a unique object pinned with the name "Message". I'm assuming that when I attempt to save the new Message() object and update the pointer in the MessageThread() this deallocates in memory the previous Message() object, which is currently being displayed to the user, even though I expressly fetched it from the pin name "Message", and crashes the app.

I hope this helps. Most likely I'm doing something that Parse never intended here. I've done my best to understand the docs on what is possible and what is not with using pinning. From my reading, what I'm attempting above should be possible....

Thanks!

@ritteraf
Copy link

ritteraf commented May 21, 2020

Since I've already wasted too much time on this issue, I decided to fall back to my logic that was working. No more error issues.

I changed the following:

  1. New Message() objects are now stored in an array within the MessageThread() object, instead of a single Message() object being passed with each thread update, and pinned separately under the "Message" name.
  2. Pinning and unpinning is only happening against the MessageThread() object. I have eliminated pinning the Message() object separately.

As you can guess, this is a bummer for me, as a chat room can have an arbitrarily large number of Message() objects, and storing them in an array is not ideal in that circumstance.

@mtrezza
Copy link
Member

mtrezza commented Jun 13, 2023

@ahsanghauri, @ritteraf The LiveQuery feature has been added as a module to the Parse Apple SDK; could you please verify that this issue is fixed there, and if not open a new issue there?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants