Skip to content

Commit

Permalink
Fix #102—Avoid retain cycle between SDCAlertView and SDCAlertController
Browse files Browse the repository at this point in the history
The shouldDismissBlock and didDismissBlock of SDCAlertView had a reference to the SDCAlertController instance that was used to instantiate the legacy alert view. Since the alert controller also had a strong reference to the legacy alert view, this caused a retain cycle. The fix is to remove the reference to the alert controller in the aforementioned blocks and copy any values needed from the controller and use those in the blocks instead.
  • Loading branch information
sberrevoets committed May 31, 2015
1 parent 0681097 commit 7ed3dbb
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 15 deletions.
2 changes: 1 addition & 1 deletion SDCAlertView/Source/SDCAlertController.m
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ - (void)presentFromViewController:(UIViewController *)viewController completionH
}

- (void)dismissWithCompletion:(void (^)(void))completion {
if ([self usesLegacyAlert]) {
if (self.usesLegacyAlert) {
self.legacyAlertView.didDismissHandler = ^(NSInteger buttonIndex) {
if (completion) {
completion();
Expand Down
30 changes: 16 additions & 14 deletions SDCAlertView/Source/SDCAlertView.m
Original file line number Diff line number Diff line change
Expand Up @@ -515,9 +515,9 @@ - (void)setLabelSpacing:(CGFloat)labelSpacing {

@implementation SDCAlertView (SDCAlertController)

+ (SDCAlertAction *)cancelActionForAlertController:(SDCAlertController *)alertController {
+ (SDCAlertAction *)cancelActionInArray:(NSArray *)actions {
__block SDCAlertAction *action;
[alertController.actions enumerateObjectsUsingBlock:^(SDCAlertAction *currentAction, NSUInteger idx, BOOL *stop) {
[actions enumerateObjectsUsingBlock:^(SDCAlertAction *currentAction, NSUInteger idx, BOOL *stop) {
if (currentAction.style == SDCAlertActionStyleCancel) {
action = currentAction;
*stop = YES;
Expand All @@ -528,7 +528,7 @@ + (SDCAlertAction *)cancelActionForAlertController:(SDCAlertController *)alertCo
}

+ (instancetype)alertViewWithAlertController:(SDCAlertController *)alertController {
SDCAlertAction *cancelAction = [self cancelActionForAlertController:alertController] ?: alertController.actions.firstObject;
SDCAlertAction *cancelAction = [self cancelActionInArray:alertController.actions] ?: alertController.actions.firstObject;
NSString *cancelActionTitle = cancelAction.title ?: cancelAction.attributedTitle.string;
SDCAlertView *alert = [[SDCAlertView alloc] initWithTitle:alertController.title
message:alertController.message
Expand Down Expand Up @@ -570,20 +570,22 @@ + (instancetype)alertViewWithAlertController:(SDCAlertController *)alertControll
alert.alwaysShowsButtonsVertically = (alertController.actionLayout == SDCAlertControllerActionLayoutVertical);

__weak typeof(alert) weakAlert = alert;
NSArray *actions = [alertController.actions copy];
BOOL(^shouldDismissBlock)(SDCAlertAction *action) = [alertController.shouldDismissBlock copy];
alert.shouldDismissHandler = ^BOOL(NSInteger buttonIndex) {
if (buttonIndex < alertController.actions.count && alertController.shouldDismissBlock) {
if (buttonIndex < actions.count && shouldDismissBlock) {
typeof(alert) strongAlert = weakAlert;
SDCAlertAction *action = [strongAlert actionForButtonIndex:buttonIndex inAlertController:alertController];
return alertController.shouldDismissBlock(action);
SDCAlertAction *action = [strongAlert actionForButtonIndex:buttonIndex inArray:actions];
return shouldDismissBlock(action);
}

return YES;
};

alert.didDismissHandler = ^(NSInteger buttonIndex) {
if (buttonIndex < alertController.actions.count) {
if (buttonIndex < actions.count) {
typeof(alert) strongAlert = weakAlert;
SDCAlertAction *action = [strongAlert actionForButtonIndex:buttonIndex inAlertController:alertController];
SDCAlertAction *action = [strongAlert actionForButtonIndex:buttonIndex inArray:actions];

if (action.handler) {
action.handler(action);
Expand All @@ -594,14 +596,14 @@ + (instancetype)alertViewWithAlertController:(SDCAlertController *)alertControll
return alert;
}

- (SDCAlertAction *)actionForButtonIndex:(NSInteger)buttonIndex inAlertController:(SDCAlertController *)alertController {
SDCAlertAction *cancelAction = [[self class] cancelActionForAlertController:alertController];
- (SDCAlertAction *)actionForButtonIndex:(NSInteger)buttonIndex inArray:(NSArray *)actions {
SDCAlertAction *cancelAction = [[self class] cancelActionInArray:actions];
if (buttonIndex == self.cancelButtonIndex) {
return cancelAction;
} else {
NSMutableArray *actions = [alertController.actions mutableCopy];
[actions removeObject:cancelAction];
return actions[buttonIndex - 1];
NSMutableArray *mutableActions = [actions mutableCopy];
[mutableActions removeObject:cancelAction];
return mutableActions[buttonIndex - 1];
}
}

Expand Down

0 comments on commit 7ed3dbb

Please sign in to comment.