Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'Target table row index out of range' after upgrading from 2.1.2 to 2.10.1 #5340

Closed
ivanicspeter92 opened this issue Sep 26, 2017 · 8 comments

Comments

@ivanicspeter92
Copy link

I came along the "Target table row index out of range" error message (also see #5008 ) and crash today after upgrading from Realm 2.1.2 to 2.10.1 (via Cocoapods). The crash happens on iOS 11 and iOS 10 devices and simulators constantly, when the execution reaches the realm.add() function call in the following snippet.

Goals

I would like to update my Realm through CocoaPods from 2.1.2 to 2.10.1.

Expected Results

The application works fine without any problems.

Actual Results

The application crashes when the execution reaches the add() call. The crash happens only for some of my Realm Object classes, which seemingly share no similarity between one another. If I comment the add() call out, my application runs smoothly without any problems. The insertOrUpdate() function in the Code sample section below is called after the app parses a JSON dictionary successfully to an object.

Steps to Reproduce

I have tried to reproduce the issue by creating a small project, but the crash does not happen with the identical database, but the crash did not occur when I was adding objects one-by-one. I suspect this may happen either because multiple objects are inserted to Realm in some cases or because it happens in a different thread other than main.

Code Sample

  func insertOrUpdate(object: Object) {
        do {
            let realm = try Realm()
            
            try realm.write {
                realm.add(object, update: true) // crash here: Target table row index out of range
            }
        } catch let error {
            print(error.localizedDescription)
        }
    }

Realm framework version: RealmSwift 2.10.1
Xcode version: xCode 8.3 and xCode 9.0
iOS/OSX version: iOS 10 and iOS 11
Dependency manager + version: CocoaPods 1.3.1

@kishikawakatsumi
Copy link
Contributor

@ivanicspeter92 Sorry for the delayed response. Could you please provide more code around crash? How is the insertOrUpdate () method called? Is it called from multiple threads? What are model definitions?

Please send to help@realm.io the small project you created if possible. Even if the problem does not reproduce, we want to know what kind of code it is.

@ivanicspeter92
Copy link
Author

@kishikawakatsumi I have put the example project to a repo here: https://github.com/ivanicspeter92/RealmCrashTest . Feel free to fork this as you like.

The project has the simplified scenario - something happens in the UI, such as a button tap, which triggers an Alamofire post or get request via the RemoteService singleton. In case of successful reply, on the callback function's thread, the JSON is parsed (this part is not in the demo but I believe it should not matter) and the aforementioned insertOrUpdate() is called in the DataManager class.

I have added only two model classes (User and Image) from our app. We have more classes obviously, around 35-40 with similar structure and cross-references among eachother. In the real scenario, when the Image objects are retrieved (I think around 50 of them at once), the crash happens as explained above. The insertOrUpdate() function is not called from multiple threads, however is always called from the callback method of the Alamofire request (which was not an issue in previous Realm versions). I have attached a new crash dump also, I hope this helps!
realm_crash_dump.txt

@kishikawakatsumi
Copy link
Contributor

@ivanicspeter92 Thanks for providing the project. But we cannot reproduce the issue on the project. I tried to run the project several times on both simulators and devices. Could you tell us more detail steps to reproduce the crash?

@ivanicspeter92
Copy link
Author

@kishikawakatsumi Unfortunately I haven't been able to reproduce the crash in the test app but I can provide some more details on the real scenario.

It seems that the crash occurs when a bunch of "complex" objects are being inserted to the database. By complex I mean that they have not only primitive fields but also references pointing to other objects (either as a field or as a list), such as Image in the test app has a reference to User.

Could you explain what the error message means more particularly? I haven't been able to find any documentation on it so it's rather difficult to say why this happens. I suspect that either the size of the objects to be inserted is too big or the maximum table size is exceeded, if there is such a case. These problems were not present in previous versions (< 2.10.1).

Thanks!

P.S. I have tried with Realm 3.0.0 and the problem still exists which blocks me of upgrading our app to Swift 4 and xCode 9 :(

@ha1f
Copy link

ha1f commented Nov 2, 2017

I got this Error when initialize some property using static let.

class UserSetting: Object {
    ・・・
    @objc dynamic var _sizeSetting: SizeSetting? = SizeSetting.M
    ・・・
}

class SizeSetting: Object {
    static let M: SizeSetting = // some value
    ・・・
}

After rewrite as follows, the error has gone.

class UserSetting: Object {
    ・・・
    @objc dynamic var _sizeSetting: SizeSetting? = SizeSetting.M()
    ・・・
}

class SizeSetting: Object {
    static func M() -> SizeSetting {
        // returns some value
    }
    ・・・
}

Needless to say, there was no error before updating Realm.

I updated from 2.9.1 to 3.0.1

- github "realm/realm-cocoa" "v2.9.1"
+github "realm/realm-cocoa" "v3.0.1"

Swift version is 4.0, and Xcode version is 9.0.1(9A1004)

@austinzheng
Copy link
Contributor

Do you have a reproduction case you can share with us that demonstrates this behavior?

@ivanicspeter92
Copy link
Author

I have got the issue resolved in my project today. I can try to update the previously provided project such that it has the same issue by tomorrow.
The problem was that I had a superclass for two model classes similar to the following snippet:

class S: RealmSwift.Object {
}

class A: S {
}

class B: S {
}

Nothing is wrong with, that in general, but then I had a fourth class with a field that is type of S, where A and B type of objects are stored.

class C: RealmSwift.Object {
@objc dynamic var field: S
}

let object = C()
object.field = B() // no compilation errors as B is a subclass of S

However, upon writing into Realm this was crashing in my project from v2.1.2 upwards.

@austinzheng
Copy link
Contributor

Thanks for the update, and for sharing your models.

Our polymorphism support isn't currently suited to handle what you want to do. B is a subclass of S, and so it's true that your code type checks, but an instance of B has more fields than an instance of S and so when you try to write a B into the database where it expects an S you get the index out of bounds error you were seeing earlier.

Also, object properties have to be declared as nullable, so field needs to be a S?.

If you have any further questions feel free to file a new ticket.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants