diff --git a/shell/platform/darwin/common/framework/Source/FlutterChannels.mm b/shell/platform/darwin/common/framework/Source/FlutterChannels.mm index a5142b11c0aa3..33ff2da28dcc7 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterChannels.mm +++ b/shell/platform/darwin/common/framework/Source/FlutterChannels.mm @@ -61,9 +61,11 @@ - (void)setMessageHandler:(FlutterMessageHandler)handler { [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:nil]; return; } + // Grab reference to avoid retain on self. + NSObject* codec = _codec; FlutterBinaryMessageHandler messageHandler = ^(NSData* message, FlutterBinaryReply callback) { - handler([_codec decode:message], ^(id reply) { - callback([_codec encode:reply]); + handler([codec decode:message], ^(id reply) { + callback([codec encode:reply]); }); }; [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:messageHandler]; @@ -208,15 +210,17 @@ - (void)setMethodCallHandler:(FlutterMethodCallHandler)handler { [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:nil]; return; } + // Make sure the block captures the codec, not self. + NSObject* codec = _codec; FlutterBinaryMessageHandler messageHandler = ^(NSData* message, FlutterBinaryReply callback) { - FlutterMethodCall* call = [_codec decodeMethodCall:message]; + FlutterMethodCall* call = [codec decodeMethodCall:message]; handler(call, ^(id result) { if (result == FlutterMethodNotImplemented) callback(nil); else if ([result isKindOfClass:[FlutterError class]]) - callback([_codec encodeErrorEnvelope:(FlutterError*)result]); + callback([codec encodeErrorEnvelope:(FlutterError*)result]); else - callback([_codec encodeSuccessEnvelope:result]); + callback([codec encodeSuccessEnvelope:result]); }); }; [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:messageHandler]; @@ -263,14 +267,13 @@ - (void)dealloc { [super dealloc]; } -- (void)setStreamHandler:(NSObject*)handler { - if (!handler) { - [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:nil]; - return; - } +static void SetStreamHandlerMessageHandlerOnChannel(NSObject* handler, + NSString* name, + NSObject* messenger, + NSObject* codec) { __block FlutterEventSink currentSink = nil; FlutterBinaryMessageHandler messageHandler = ^(NSData* message, FlutterBinaryReply callback) { - FlutterMethodCall* call = [_codec decodeMethodCall:message]; + FlutterMethodCall* call = [codec decodeMethodCall:message]; if ([call.method isEqual:@"listen"]) { if (currentSink) { FlutterError* error = [handler onCancelWithArguments:nil]; @@ -280,36 +283,43 @@ - (void)setStreamHandler:(NSObject*)handler { } currentSink = ^(id event) { if (event == FlutterEndOfEventStream) - [_messenger sendOnChannel:_name message:nil]; + [messenger sendOnChannel:name message:nil]; else if ([event isKindOfClass:[FlutterError class]]) - [_messenger sendOnChannel:_name - message:[_codec encodeErrorEnvelope:(FlutterError*)event]]; + [messenger sendOnChannel:name message:[codec encodeErrorEnvelope:(FlutterError*)event]]; else - [_messenger sendOnChannel:_name message:[_codec encodeSuccessEnvelope:event]]; + [messenger sendOnChannel:name message:[codec encodeSuccessEnvelope:event]]; }; FlutterError* error = [handler onListenWithArguments:call.arguments eventSink:currentSink]; if (error) - callback([_codec encodeErrorEnvelope:error]); + callback([codec encodeErrorEnvelope:error]); else - callback([_codec encodeSuccessEnvelope:nil]); + callback([codec encodeSuccessEnvelope:nil]); } else if ([call.method isEqual:@"cancel"]) { if (!currentSink) { callback( - [_codec encodeErrorEnvelope:[FlutterError errorWithCode:@"error" - message:@"No active stream to cancel" - details:nil]]); + [codec encodeErrorEnvelope:[FlutterError errorWithCode:@"error" + message:@"No active stream to cancel" + details:nil]]); return; } currentSink = nil; FlutterError* error = [handler onCancelWithArguments:call.arguments]; if (error) - callback([_codec encodeErrorEnvelope:error]); + callback([codec encodeErrorEnvelope:error]); else - callback([_codec encodeSuccessEnvelope:nil]); + callback([codec encodeSuccessEnvelope:nil]); } else { callback(nil); } }; - [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:messageHandler]; + [messenger setMessageHandlerOnChannel:name binaryMessageHandler:messageHandler]; +} + +- (void)setStreamHandler:(NSObject*)handler { + if (!handler) { + [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:nil]; + return; + } + SetStreamHandlerMessageHandlerOnChannel(handler, _name, _messenger, _codec); } @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h b/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h index df668dd2a341c..af5c82f2012a1 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h @@ -5,7 +5,7 @@ #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" -#ifndef NDEBUG +#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG FLUTTER_EXPORT #endif @interface FlutterBinaryMessengerRelay : NSObject