2

I'm getting EXC_BAD_ACCESS exceptions on the managedObject.objectRevision access in the following code:

-(void)increaseObjectRevision {
    __weak LibraryManagedObject* weakSelf = self;
    dispatch_async(dispatch_get_main_queue(), ^{
        LibraryManagedObject* managedObject = weakSelf;
        if(managedObject) {
            managedObject.objectRevision = managedObject.objectRevision + 1;
        }
    });
}

I'm a little stumped as this code pattern seems to be the solution referred to in Strong reference to a weak references inside blocks

Here's the declaration for the objectRevision property:

@interface LibraryManagedObject : NSObject
@property (readonly, nonatomic) NSUInteger objectRevision;
...
@end

And re-defined within the LibraryManagedObject.m to:

@interface LibraryManagedObject()
@property (readwrite, nonatomic, assign) NSUInteger objectRevision;
@end

Anything I'm missing here?

Note: I could make the property atomic but seeing how this is not a pointer to a NSNumber but a value itself, it shouldn't be the cause for the EXC_BAD_ACCESS exception.

ekscrypto
  • 3,718
  • 1
  • 24
  • 38
  • 1. Why main thread? -------------------- 2. Managed object is nil at moment of increasing revision or what? – Ilya Muradymov Jul 24 '20 at 14:09
  • 1
    @IlyaMuradymov so that the observers on the property are notified on the main thread – ekscrypto Jul 24 '20 at 14:41
  • re-defining (readwrite) in LibraryManagedObject() makes it accessible from inside the class which is not wrong but declare a public method that will increase objectRevision; and invoke that instead. – Ol Sen Jul 24 '20 at 14:44
  • if -(void)increaseObjectRevision is part of LibraryManagedObject Class you are actually invoking a method that goes async accessing the property from outside which is readonly. – Ol Sen Jul 24 '20 at 14:49
  • @OlSen please review https://stackoverflow.com/questions/5008060/objective-c-property-that-is-readonly-publicly-but-has-a-private-setter – ekscrypto Jul 24 '20 at 14:52
  • yes correct, but if that answer would be complete it could work. Who is accessing objectRevision from Where, outside or inside? async is async. – Ol Sen Jul 24 '20 at 14:55
  • @OlSen other classes are using the publicly defined -increaseObjectRevision, which then triggers the async block. We are not declaring the readwrite access to .objectRevision publicly but any piece of code anywhere would be able to update the writeable accessor the same way people are able to use Apple's internal API if they declare the proper headers. Objective-C does not prevent or restrict access to internal functions, only the declaration of those functions exposes them or not to other classes. – ekscrypto Jul 24 '20 at 14:58
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/218530/discussion-between-ol-sen-and-ekscrypto). – Ol Sen Jul 24 '20 at 14:59

1 Answers1

2

The code posted in the question is working as intended. After inspecting the memory address reported in the exception against the value of weakSelf, the addresses were different.

During our discussion (https://chat.stackoverflow.com/rooms/218530/discussion-between-ol-sen-and-ekscrypto) it became clear that KVO may actually be related to the crash. One of the KVO observers did not properly unregister its observer before being deallocated.

ekscrypto
  • 3,718
  • 1
  • 24
  • 38