1

How to tell ARC do not release objects in main thread, which are used in another thread? How to prevent releasing?

-(void)someFunc
{
    array = ... //fetching array of entities from a core data
    for(SomeObject * obj in array)
    {
         NSSomeOperation * op = [[NSSomeOperation alloc] initWithValue:obj];
         //start operation
    }
    //it seems here ARC release array and all items  
}

The array is fetched from a Core Data.

ruslan.berliner
  • 121
  • 2
  • 13
  • You have a custom NSOperation or you're really calling `initWithValue:` on NSOperation? – gcamp Feb 25 '12 at 22:10
  • Custom. I've updated the text of the question. – ruslan.berliner Feb 25 '12 at 22:12
  • 1
    your problem is not ARC, it's the fact that you are trying to share managed objects between threads. CoreData is not thread safe and you need to use a separate context and fetch your managed objects for each thread. – Rog Feb 26 '12 at 09:42
  • Before ARC everything was fine. When I turned on ARC - this releasing of the objects. I'm using objectWithID on NSSomeOperation. This ARC behavior causes another error - [link](http://stackoverflow.com/questions/9419048/exc-bad-access-on-nsmanagedobjectcontext-save-method-inside-nsoperation-and-arc) – ruslan.berliner Feb 26 '12 at 09:48
  • Thanks Rog, I will take this into consideration. – ruslan.berliner Feb 26 '12 at 09:54
  • @Rog Why Core Data is not thread-safe?:) – ruslan.berliner Feb 26 '12 at 11:02
  • @Rog Many thanks! It resolved my issue and linked issue, I'm not passing now managed objects and it seems working, I hope. Before ARC I've used separate managed object context and objectWithID and everything was fine. – ruslan.berliner Feb 26 '12 at 11:36
  • https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/Concurrency.html – James Bush Apr 21 '17 at 22:37

4 Answers4

2

I have the same problem with ARC and fetching results using FetchResultController. I load the records first then I feed a tableView with them, it goes well at the first but when I scroll or I select any row, the managed objects inside the array become "nil".

The cause is: I forgot a small __strong for the object I'm creating that contains all the Core Data fetch I need.

nhahtdh
  • 55,989
  • 15
  • 126
  • 162
DigitalVanilla
  • 214
  • 2
  • 12
1

You need to have a strong reference to that object in your NSSomeOperation.

If you're using a property :

@property (nonatomic, strong) SomeObject *value;

If you're using a ivar :

__strong SomeObject *value;

Look at the transition guide for ARC.

gcamp
  • 14,622
  • 4
  • 54
  • 85
  • Thanks, I'm using this already, but it doesn't help. The array is fetched from a Core Data. I've updated the text of the question. – ruslan.berliner Feb 26 '12 at 09:22
1

Rather than mess about with keeping a strong reference to the array and evaluating each element with an NSOperation, you can get a similar concurrent enumeration using blocks:

-(void)someFunc
{
    array = ... //get array from another function
    [array enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        // Perform the operation on each obj in this block
        // The blocks will run concurrently
    }
}
Abizern
  • 146,289
  • 39
  • 203
  • 257
  • Thanks, I've never used this before. But it is not good design solution. Using of NSOperation is more preferable. Because the body of the processing can be very big. OOP is more preferable. – ruslan.berliner Feb 26 '12 at 09:33
  • @igelekle Take a look at Blocks and GCD again. There is nothing non-OOP about them. – Abizern Feb 26 '12 at 11:40
  • Okey, I'm learning now GCD, it seems much faster than nsoperations. I think Block can be used for small pieces of code, for inlining some small operation. For more complex processing I think nsperations and GCD much better. I resolved this issue, see my comment above. – ruslan.berliner Feb 26 '12 at 11:54
0

The problem is I'm trying to share managed objects between threads. CoreData is not thread safe and you need to use a separate context and fetch your managed objects for each thread. ARC releases core data objects.

ruslan.berliner
  • 121
  • 2
  • 13