开发者

Setting attribute of NSManagedObject is blocking the iPad UI' in Core Data

开发者 https://www.devze.com 2023-03-20 19:29 出处:网络
Firstly, I have found a couple of related questions on the issue with links pasted below, but none have really helped me solve the problem:

Firstly, I have found a couple of related questions on the issue with links pasted below, but none have really helped me solve the problem:

iPhone Co开发者_如何学编程reData properties: changes to managedObjects are too slow

iOS CoreData: NSFetchedResultsController performances

I have a tableview with approximately 5,000 rows that is currently being managed by a fetched results controller.

Each row displays basic attributes of a Document entity, and also includes a button for users to tag a specific Document as favourite. Admittedly, the Document entity has relationships with a few different entities and the underlying SQLite database is largeish (~20mb).

Fetching the attributes for each row is relatively quick and the table view performs quite well with that many items. Saving changes is not an issue either.

My problem arises when I try to change the isFavourite (BOOL) attribute of my Document entity. This attribute gets set / updated on a button touch up inside event with:

[document setIsFavourite:[NSNumber numberWithBool:![document isFavourite]]]

The issue here is that on every tap of the Favourite button, this particular line of code blocks the UI for ~1-2 secs which is obviously not ideal.

I have tried marking the isFavourite attribute as indexed, as well as increasing the fetch batch size and finally creating a cache for the NSFetchedResultsController but nothing seems to help with performance.

The only way that I managed to avoid the UI lock was to perform the attribute setting on a background thread, but this involves creating a new context, registering for notifications and merging changes when the context is saved. In this case another issue comes up, as when I respond to the save notification with merge changes, my fetched results controller seems to get confused and the changed row is removed from my tableview automatically, and the only way to get it back is to do a [tableview reloadData].

Has anyone else experience a similar problem and is there anything else I could try to fix it?

Many thanks in advance,

Rog


That line shouldn't cause a hang because nothing has to be fetched. You already have the document object in memory and you are changing just a single attribute of that object also in memory.

I can think of only two reasons why such a line would cause a hang.

First, you have a custom accessor for setIsFavourite: that triggers side effects which drive faulting and fetches. E.g. You have custom logic that triggers when the isFavourite attribute changes that triggers a fetched property.

I lean towards this explanation because you are using the old reference form instead of:

document.isFavourite=[NSNumber numberWithBool:![document isFavourite]];

If you created the class of the document object by hand, check that you used @dynamic instead of @synthesize for the properties. The later will not work well with NSManagedObject subclasses.

Secondly, you have validation set on the attribute that triggers a similar cascade e.g. the validation has to check a property in another object.

I am rather dubious that the line of code is actually the source of the problem.

0

精彩评论

暂无评论...
验证码 换一张
取 消