Merge pull request #3531 from dreampiggy/bugfix/macos_SDDisplayLink_crash_during_dealloc
Try to fix macOS SDDisplayLink crash because of accessing the deallocated objc pointer during CVDisplayLinkRef callback
This commit is contained in:
commit
d82f5574e4
|
@ -45,6 +45,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
|||
- (void)dealloc {
|
||||
#if SD_MAC
|
||||
if (_displayLink) {
|
||||
CVDisplayLinkStop(_displayLink);
|
||||
CVDisplayLinkRelease(_displayLink);
|
||||
_displayLink = NULL;
|
||||
}
|
||||
|
@ -62,14 +63,15 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
|||
if (self) {
|
||||
_target = target;
|
||||
_selector = sel;
|
||||
// CA/CV/NSTimer will retain to the target, we need to break this using weak proxy
|
||||
SDWeakProxy *weakProxy = [SDWeakProxy proxyWithTarget:self];
|
||||
#if SD_MAC
|
||||
CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
|
||||
CVDisplayLinkSetOutputCallback(_displayLink, DisplayLinkCallback, (__bridge void *)self);
|
||||
// Simulate retain for target, the target is weak proxy to self
|
||||
CVDisplayLinkSetOutputCallback(_displayLink, DisplayLinkCallback, (__bridge_retained void *)weakProxy);
|
||||
#elif SD_IOS || SD_TV
|
||||
SDWeakProxy *weakProxy = [SDWeakProxy proxyWithTarget:self];
|
||||
_displayLink = [CADisplayLink displayLinkWithTarget:weakProxy selector:@selector(displayLinkDidRefresh:)];
|
||||
#else
|
||||
SDWeakProxy *weakProxy = [SDWeakProxy proxyWithTarget:self];
|
||||
_displayLink = [NSTimer timerWithTimeInterval:kSDDisplayLinkInterval target:weakProxy selector:@selector(displayLinkDidRefresh:) userInfo:nil repeats:YES];
|
||||
#endif
|
||||
}
|
||||
|
@ -238,7 +240,9 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
|||
#if SD_MAC
|
||||
static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *inNow, const CVTimeStamp *inOutputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext) {
|
||||
// CVDisplayLink callback is not on main queue
|
||||
// Actually `SDWeakProxy` but not `SDDisplayLink`
|
||||
SDDisplayLink *object = (__bridge SDDisplayLink *)displayLinkContext;
|
||||
if (!object) return kCVReturnSuccess;
|
||||
// CVDisplayLink does not use runloop, but we can provide similar behavior for modes
|
||||
// May use `default` runloop to avoid extra callback when in `eventTracking` (mouse drag, scroll) or `modalPanel` (modal panel)
|
||||
NSString *runloopMode = object.runloopMode;
|
||||
|
|
Loading…
Reference in New Issue