سؤال

I have a C++ static library that is linked in my iOS app. I have a void* to it in order to access some actions provided by the library from my code. The problem is that i have activated ARC on my project and it screams that in a block where the void* is called a retain cycle is generated.

the code that generates the retain cycle warning looks like below:

self.panGestureBlock = ^(UIGestureRecognizerState state, CGPoint point, CGPoint velocity) {
      [strongStreamClient onWorkerThreadDoBlock:^{
        LibGesture(libInstance, ATU_GESTURE_TYPE_PAN, GestureStateFromUIKitToLib(state), point.x, point.y, velocity.x, velocity.y); 
      }];
    };

when i pass as a parameter the libInstance pointer to the function it gives a warning like this:

Capturing 'self' strongly in this block is likely to lead to a retain cycle

if i try to do something like this:

__weak void* weakLibInstance = libInstance;

    self.panGestureBlock = ^(UIGestureRecognizerState state, CGPoint point, CGPoint velocity) {
      [self onWorkerThreadDoBlock:^{
        void* strongLibInstance = weakLibInstance;
        LibGesture(strongLibInstance, ATU_GESTURE_TYPE_PAN, GestureStateFromUIKitToLib(state), point.x, point.y, velocity.x, velocity.y); 
      }];
    };

it gives a warning like below:

'__weak' only applies to objective-c object or block pointer types; type here is 'void *'

which is pretty clear.. the question is how do i get over this retain cycle? any pointers?

هل كانت مفيدة؟

المحلول

The __weak modifier only applies to pointers to Objective-C objects. You can't use it with a void*, but in this case you don't need to. Just remove it from the variable declaration and your code should work (assuming you don't destroy the library instance before calling the block).

نصائح أخرى

you need to wrap all reference to self in block to by a weak reference. this include access to any ivar

__weak __block id blockSelf = self;
self.panGestureBlock = ^(UIGestureRecognizerState state, CGPoint point, CGPoint velocity) {
      [strongStreamClient onWorkerThreadDoBlock:^{
        LibGesture(blockSelf->libInstance, ATU_GESTURE_TYPE_PAN, GestureStateFromUIKitToLib(state), point.x, point.y, velocity.x, velocity.y);
      //assume libInstance is an ivar
      }];
    };
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top