Skip to content

Commit

Permalink
Fixed memory leak by way of accidental retain on implicit self (flutt…
Browse files Browse the repository at this point in the history
…er#9329)

Fixed memory leak by way of accidental retain on implicit self.
  • Loading branch information
gaaclarke authored Jun 28, 2019
1 parent e96900d commit 7a0bbf9
Showing 1 changed file with 33 additions and 23 deletions.
56 changes: 33 additions & 23 deletions shell/platform/darwin/common/framework/Source/FlutterChannels.mm
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ - (void)setMessageHandler:(FlutterMessageHandler)handler {
[_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:nil];
return;
}
// Grab reference to avoid retain on self.
NSObject<FlutterMessageCodec>* 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];
Expand Down Expand Up @@ -208,15 +210,17 @@ - (void)setMethodCallHandler:(FlutterMethodCallHandler)handler {
[_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:nil];
return;
}
// Make sure the block captures the codec, not self.
NSObject<FlutterMethodCodec>* 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];
Expand Down Expand Up @@ -263,14 +267,13 @@ - (void)dealloc {
[super dealloc];
}

- (void)setStreamHandler:(NSObject<FlutterStreamHandler>*)handler {
if (!handler) {
[_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:nil];
return;
}
static void SetStreamHandlerMessageHandlerOnChannel(NSObject<FlutterStreamHandler>* handler,
NSString* name,
NSObject<FlutterBinaryMessenger>* messenger,
NSObject<FlutterMethodCodec>* 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];
Expand All @@ -280,36 +283,43 @@ - (void)setStreamHandler:(NSObject<FlutterStreamHandler>*)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<FlutterStreamHandler>*)handler {
if (!handler) {
[_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:nil];
return;
}
SetStreamHandlerMessageHandlerOnChannel(handler, _name, _messenger, _codec);
}
@end

0 comments on commit 7a0bbf9

Please sign in to comment.