iPlug2 / iPlug2

C++ Audio Plug-in Framework for desktop, mobile and web
https://iplug2.github.io
Other
1.92k stars 284 forks source link

IOS platform text entry cancel button doesn't cancel (still commits the edit) #968

Closed AlexHarker closed 1 year ago

AlexHarker commented 1 year ago

Describe the bug When entering values on IOS using the platform text entry the cancel button doesn't cancel and the the edit is still committed.

To Reproduce Do as described above.

Expected behaviour The edit should be cancelled and have no effect.

IMPORTANT DETAILS

IOS AUv3 only.

olilarkin commented 1 year ago

LG, but i think we need weak references to self otherwise we create a retain cycle. from chatGPT:

In Objective-C, you should use a weak reference to self in a completion handler (or any other block that is stored and executed later) to avoid a retain cycle, also known as a strong reference cycle or a memory leak.

A retain cycle occurs when two or more objects hold strong references to each other, preventing each other from being deallocated even when they're no longer needed. This can lead to an increased memory footprint and potentially cause your app to crash if it consumes too much memory.

Here's an example of how you might create a retain cycle:

// Assuming you're inside a method of 'self'
self.completionHandler = ^{
    [self doSomething];  // This creates a retain cycle
};

In the above example, self holds a strong reference to the block via self.completionHandler, and the block holds a strong reference to self because it captures self in its body. This creates a retain cycle.

To break the retain cycle, you can capture self as a weak reference inside the block:

__weak typeof(self) weakSelf = self;
self.completionHandler = ^{
    [weakSelf doSomething];  // This does not create a retain cycle
};

In this case, self still holds a strong reference to the block via self.completionHandler, but the block now holds a weak reference to self. This means that self can be deallocated even if the block is not yet deallocated, breaking the retain cycle.

It's important to note that when you use a weak reference, the referenced object can be deallocated at any time. So, inside the block, you should convert the weak reference back to a strong one to ensure it stays alive during the block's execution:

__weak typeof(self) weakSelf = self;
self.completionHandler = ^{
    __strong typeof(self) strongSelf = weakSelf;
    if (strongSelf) {
        [strongSelf doSomething];
    }
};

This way, strongSelf is either nil (if self has been deallocated) or a temporary strong reference to self (which is deallocated when the block finishes executing), and you avoid a retain cycle.

AlexHarker commented 1 year ago

I've updated to address this.

olilarkin commented 1 year ago

oops i commented on the issue not the pr