-
Notifications
You must be signed in to change notification settings - Fork 522
fix: Avoid keeping strong reference to self instance in delegates #1123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2f20864
720bfe2
6bf09b8
830d551
b6cfe5c
e485a8b
e93099b
7ab55db
3498781
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -47,10 +47,16 @@ @interface FBWebServer () | |||||||||||
| @property (nonatomic, strong) RoutingHTTPServer *server; | ||||||||||||
| @property (atomic, assign) BOOL keepAlive; | ||||||||||||
| @property (nonatomic, nullable) FBTCPSocket *screenshotsBroadcaster; | ||||||||||||
| @property (nonatomic, nullable, strong) FBMjpegServer *mjpegServer; | ||||||||||||
| @end | ||||||||||||
|
|
||||||||||||
| @implementation FBWebServer | ||||||||||||
|
|
||||||||||||
| - (void)dealloc | ||||||||||||
| { | ||||||||||||
| [self stopScreenshotsBroadcaster]; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| + (NSArray<Class<FBCommandHandler>> *)collectCommandHandlerClasses | ||||||||||||
| { | ||||||||||||
| NSArray *handlersClasses = FBClassesThatConformsToProtocol(@protocol(FBCommandHandler)); | ||||||||||||
|
|
@@ -97,7 +103,7 @@ - (void)startHTTPServer | |||||||||||
| [self.server setInterface:bindingIP]; | ||||||||||||
| [FBLogger logFmt:@"Using custom binding IP address: %@", bindingIP]; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| NSError *error; | ||||||||||||
| BOOL serverStarted = NO; | ||||||||||||
|
|
||||||||||||
|
|
@@ -117,31 +123,42 @@ - (void)startHTTPServer | |||||||||||
| [FBLogger logFmt:@"Last attempt to start web server failed with error %@", [error description]]; | ||||||||||||
| abort(); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| NSString *serverHost = bindingIP ?: ([XCUIDevice sharedDevice].fb_wifiIPAddress ?: @"127.0.0.1"); | ||||||||||||
| [FBLogger logFmt:@"%@http://%@:%d%@", FBServerURLBeginMarker, serverHost, [self.server port], FBServerURLEndMarker]; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| - (void)initScreenshotsBroadcaster | ||||||||||||
| { | ||||||||||||
| [self readMjpegSettingsFromEnv]; | ||||||||||||
| self.mjpegServer = [[FBMjpegServer alloc] init]; | ||||||||||||
| self.screenshotsBroadcaster = [[FBTCPSocket alloc] | ||||||||||||
| initWithPort:(uint16_t)FBConfiguration.mjpegServerPort]; | ||||||||||||
| self.screenshotsBroadcaster.delegate = [[FBMjpegServer alloc] init]; | ||||||||||||
| self.screenshotsBroadcaster.delegate = self.mjpegServer; | ||||||||||||
| NSError *error; | ||||||||||||
|
mykola-mokhnach marked this conversation as resolved.
|
||||||||||||
| if (![self.screenshotsBroadcaster startWithError:&error]) { | ||||||||||||
| [FBLogger logFmt:@"Cannot init screenshots broadcaster service on port %@. Original error: %@", @(FBConfiguration.mjpegServerPort), error.description]; | ||||||||||||
| [self.mjpegServer stopStreaming]; | ||||||||||||
| self.mjpegServer = nil; | ||||||||||||
| self.screenshotsBroadcaster = nil; | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| - (void)stopScreenshotsBroadcaster | ||||||||||||
| { | ||||||||||||
| if (nil == self.screenshotsBroadcaster) { | ||||||||||||
| self.mjpegServer = nil; | ||||||||||||
| return; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| id<FBTCPSocketDelegate> delegate = self.screenshotsBroadcaster.delegate; | ||||||||||||
| if ([(NSObject *)delegate respondsToSelector:@selector(stopStreaming)]) { | ||||||||||||
| [(FBMjpegServer *)delegate stopStreaming]; | ||||||||||||
|
Comment on lines
+154
to
+156
|
||||||||||||
| id<FBTCPSocketDelegate> delegate = self.screenshotsBroadcaster.delegate; | |
| if ([(NSObject *)delegate respondsToSelector:@selector(stopStreaming)]) { | |
| [(FBMjpegServer *)delegate stopStreaming]; | |
| if (nil != self.mjpegServer) { | |
| [self.mjpegServer stopStreaming]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's ok
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,7 @@ @interface FBImageProcessor () | |
| @property (nonatomic) NSData *nextImage; | ||
| @property (nonatomic, readonly) NSLock *nextImageLock; | ||
| @property (nonatomic, readonly) dispatch_queue_t scalingQueue; | ||
| @property (atomic, assign) BOOL isScalingScheduled; | ||
|
|
||
| @end | ||
|
|
||
|
|
@@ -38,6 +39,7 @@ - (id)init | |
| if (self) { | ||
| _nextImageLock = [[NSLock alloc] init]; | ||
| _scalingQueue = dispatch_queue_create("image.scaling.queue", NULL); | ||
| _isScalingScheduled = NO; | ||
| } | ||
| return self; | ||
| } | ||
|
|
@@ -51,32 +53,45 @@ - (void)submitImageData:(NSData *)image | |
| [FBLogger verboseLog:@"Discarding screenshot"]; | ||
| } | ||
| self.nextImage = image; | ||
| BOOL shouldSchedule = !self.isScalingScheduled; | ||
| if (shouldSchedule) { | ||
| self.isScalingScheduled = YES; | ||
| } | ||
| [self.nextImageLock unlock]; | ||
| if (!shouldSchedule) { | ||
| return; | ||
| } | ||
|
Comment on lines
55
to
+63
|
||
|
|
||
| #pragma clang diagnostic push | ||
| #pragma clang diagnostic ignored "-Wcompletion-handler" | ||
| dispatch_async(self.scalingQueue, ^{ | ||
| [self.nextImageLock lock]; | ||
| NSData *nextImageData = self.nextImage; | ||
| self.nextImage = nil; | ||
| [self.nextImageLock unlock]; | ||
| if (nextImageData == nil) { | ||
| return; | ||
| } | ||
| while (YES) { | ||
| @autoreleasepool { | ||
| [self.nextImageLock lock]; | ||
| NSData *nextImageData = self.nextImage; | ||
| self.nextImage = nil; | ||
| if (nextImageData == nil) { | ||
| self.isScalingScheduled = NO; | ||
| [self.nextImageLock unlock]; | ||
| return; | ||
| } | ||
| [self.nextImageLock unlock]; | ||
|
|
||
| // We do not want this value to be too high because then we get images larger in size than original ones | ||
| // Although, we also don't want to lose too much of the quality on recompression | ||
| CGFloat recompressionQuality = MAX(0.9, | ||
| MIN(FBMaxCompressionQuality, FBConfiguration.mjpegServerScreenshotQuality / 100.0)); | ||
| NSData *thumbnailData = [self.class fixedImageDataWithImageData:nextImageData | ||
| scalingFactor:scalingFactor | ||
| uti:UTTypeJPEG | ||
| compressionQuality:recompressionQuality | ||
| // iOS always returns screnshots in portrait orientation, but puts the real value into the metadata | ||
| // Use it with care. See https://github.com/appium/WebDriverAgent/pull/812 | ||
| fixOrientation:FBConfiguration.mjpegShouldFixOrientation | ||
| desiredOrientation:nil]; | ||
| completionHandler(thumbnailData ?: nextImageData); | ||
| // We do not want this value to be too high because then we get images larger in size than original ones | ||
| // Although, we also don't want to lose too much of the quality on recompression | ||
| CGFloat recompressionQuality = MAX(0.9, | ||
| MIN(FBMaxCompressionQuality, FBConfiguration.mjpegServerScreenshotQuality / 100.0)); | ||
| NSData *thumbnailData = [self.class fixedImageDataWithImageData:nextImageData | ||
| scalingFactor:scalingFactor | ||
| uti:UTTypeJPEG | ||
| compressionQuality:recompressionQuality | ||
| // iOS always returns screenshots in portrait orientation, but puts the real value into the metadata | ||
| // Use it with care. See https://github.com/appium/WebDriverAgent/pull/812 | ||
| fixOrientation:FBConfiguration.mjpegShouldFixOrientation | ||
| desiredOrientation:nil]; | ||
| completionHandler(thumbnailData ?: nextImageData); | ||
| } | ||
| } | ||
| }); | ||
| #pragma clang diagnostic pop | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.