From 886972b52be304539e8f4fe2b6b9b2a44efc611b Mon Sep 17 00:00:00 2001 From: Hongzhi Zhao Date: Sun, 15 Jan 2017 12:45:36 +0800 Subject: [PATCH] Fix retain cycle --- RMUniversalAlert.m | 58 ++++++++++++++----- Tests/Podfile | 10 +++- .../project.pbxproj | 49 +++++++++++----- .../AppIcon.appiconset/Contents.json | 25 ++++++++ 4 files changed, 110 insertions(+), 32 deletions(-) diff --git a/RMUniversalAlert.m b/RMUniversalAlert.m index 1b7e998..76a7eea 100644 --- a/RMUniversalAlert.m +++ b/RMUniversalAlert.m @@ -10,6 +10,8 @@ #import "UIActionSheet+Blocks.h" #import "UIAlertController+Blocks.h" +#import "objc/runtime.h" + #import "RMUniversalAlert.h" static NSInteger const RMUniversalAlertNoButtonExistsIndex = -1; @@ -46,6 +48,11 @@ + (instancetype)showAlertInViewController:(UIViewController *)viewController alert.hasDestructiveButton = destructiveButtonTitle != nil; alert.hasOtherButtons = otherButtonTitles.count > 0; + __weak RMUniversalAlert *weakAlert = alert; + __weak UIViewController *weakViewController = viewController; + NSString *alertRefString = [NSString stringWithFormat:@"%p",alert]; + objc_setAssociatedObject(viewController, (__bridge void *)alertRefString, alert, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + if ([UIAlertController class]) { alert.alertController = [UIAlertController showAlertInViewController:viewController withTitle:title message:message @@ -53,9 +60,12 @@ + (instancetype)showAlertInViewController:(UIViewController *)viewController destructiveButtonTitle:destructiveButtonTitle otherButtonTitles:otherButtonTitles tapBlock:^(UIAlertController *controller, UIAlertAction *action, NSInteger buttonIndex){ + __strong RMUniversalAlert *strongAlert = weakAlert; + __strong UIViewController *strongViewController = weakViewController; if (tapBlock) { - tapBlock(alert, buttonIndex); + tapBlock(strongAlert, buttonIndex); } + objc_setAssociatedObject(strongViewController, (__bridge void *)alertRefString, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); }]; } else { NSMutableArray *other = [NSMutableArray array]; @@ -73,24 +83,26 @@ + (instancetype)showAlertInViewController:(UIViewController *)viewController cancelButtonTitle:cancelButtonTitle otherButtonTitles:other tapBlock:^(UIAlertView *alertView, NSInteger buttonIndex){ + __strong RMUniversalAlert *strongAlert = weakAlert; + __strong UIViewController *strongViewController = weakViewController; if (tapBlock) { if (buttonIndex == alertView.cancelButtonIndex) { - tapBlock(alert, RMUniversalAlertCancelButtonIndex); + tapBlock(strongAlert, RMUniversalAlertCancelButtonIndex); } else if (destructiveButtonTitle) { if (buttonIndex == alertView.firstOtherButtonIndex) { - tapBlock(alert, RMUniversalAlertDestructiveButtonIndex); + tapBlock(strongAlert, RMUniversalAlertDestructiveButtonIndex); } else if (otherButtonTitles.count) { NSInteger otherOffset = buttonIndex - alertView.firstOtherButtonIndex; - tapBlock(alert, RMUniversalAlertFirstOtherButtonIndex + otherOffset - 1); + tapBlock(strongAlert, RMUniversalAlertFirstOtherButtonIndex + otherOffset - 1); } } else if (otherButtonTitles.count) { NSInteger otherOffset = buttonIndex - alertView.firstOtherButtonIndex; - tapBlock(alert, RMUniversalAlertFirstOtherButtonIndex + otherOffset); + tapBlock(strongAlert, RMUniversalAlertFirstOtherButtonIndex + otherOffset); } } + objc_setAssociatedObject(strongViewController, (__bridge void *)alertRefString, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); }]; } - return alert; } @@ -109,6 +121,11 @@ + (instancetype)showActionSheetInViewController:(UIViewController *)viewControll alert.hasDestructiveButton = destructiveButtonTitle != nil; alert.hasOtherButtons = otherButtonTitles.count > 0; + __weak RMUniversalAlert *weakAlert = alert; + __weak UIViewController *weakViewController = viewController; + NSString *alertRefString = [NSString stringWithFormat:@"%p",alert]; + objc_setAssociatedObject(viewController, (__bridge void *)alertRefString, alert, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + if ([UIAlertController class]) { alert.alertController = [UIAlertController showActionSheetInViewController:viewController @@ -129,32 +146,41 @@ + (instancetype)showActionSheetInViewController:(UIViewController *)viewControll } } tapBlock:^(UIAlertController *controller, UIAlertAction *action, NSInteger buttonIndex){ + __strong RMUniversalAlert *strongAlert = weakAlert; + __strong UIViewController *strongViewController = weakViewController; if (tapBlock) { - tapBlock(alert, buttonIndex); + tapBlock(strongAlert, buttonIndex); } + objc_setAssociatedObject(strongViewController, (__bridge void *)alertRefString, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); }]; } else { void(^actionSheetTapBlock)(UIActionSheet *actionSheet, NSInteger buttonIndex) = ^(UIActionSheet *actionSheet, NSInteger buttonIndex){ + __strong RMUniversalAlert *strongAlert = weakAlert; + __strong UIViewController *strongViewController = weakViewController; if (tapBlock) { if (buttonIndex == actionSheet.cancelButtonIndex) { - tapBlock(alert, RMUniversalAlertCancelButtonIndex); + tapBlock(strongAlert, RMUniversalAlertCancelButtonIndex); } else if (buttonIndex == actionSheet.destructiveButtonIndex) { - tapBlock(alert, RMUniversalAlertDestructiveButtonIndex); + tapBlock(strongAlert, RMUniversalAlertDestructiveButtonIndex); } else if (otherButtonTitles.count) { NSInteger otherOffset = buttonIndex - actionSheet.firstOtherButtonIndex; - tapBlock(alert, RMUniversalAlertFirstOtherButtonIndex + otherOffset); + tapBlock(strongAlert, RMUniversalAlertFirstOtherButtonIndex + otherOffset); } } + objc_setAssociatedObject(strongViewController, (__bridge void *)alertRefString, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); }; void (^standardActionSheetBlock)(void) = ^{ - alert.actionSheet = [UIActionSheet showInView:viewController.view - withTitle:title - cancelButtonTitle:cancelButtonTitle - destructiveButtonTitle:destructiveButtonTitle - otherButtonTitles:otherButtonTitles - tapBlock:actionSheetTapBlock]; + __strong RMUniversalAlert *strongAlert = weakAlert; + __strong UIViewController *strongViewController = weakViewController; + strongAlert.actionSheet = [UIActionSheet showInView:strongViewController.view + withTitle:title + cancelButtonTitle:cancelButtonTitle + destructiveButtonTitle:destructiveButtonTitle + otherButtonTitles:otherButtonTitles + tapBlock:actionSheetTapBlock]; + objc_setAssociatedObject(strongViewController, (__bridge void *)alertRefString, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); }; if (popoverPresentationControllerBlock) { diff --git a/Tests/Podfile b/Tests/Podfile index 7eaf674..9e98989 100644 --- a/Tests/Podfile +++ b/Tests/Podfile @@ -2,6 +2,10 @@ source 'https://github.com/CocoaPods/Specs.git' platform :ios, '7.0' -pod 'UIAlertView+Blocks', '>= 0.8' -pod 'UIActionSheet+Blocks', '>= 0.8' -pod 'UIAlertController+Blocks', '>= 0.8' \ No newline at end of file +target 'RMUniversalAlert' do + + pod 'UIAlertView+Blocks', '>= 0.8' + pod 'UIActionSheet+Blocks', '>= 0.8' + pod 'UIAlertController+Blocks', '>= 0.8' + +end \ No newline at end of file diff --git a/Tests/RMUniversalAlert.xcodeproj/project.pbxproj b/Tests/RMUniversalAlert.xcodeproj/project.pbxproj index f3901b9..01c6b99 100644 --- a/Tests/RMUniversalAlert.xcodeproj/project.pbxproj +++ b/Tests/RMUniversalAlert.xcodeproj/project.pbxproj @@ -7,7 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - 16934E8D69700F79028CB83D /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F25F13F1C0362E837894225 /* libPods.a */; }; + 26B30820B5E36FA868140C6A /* libPods-RMUniversalAlert.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 587742414B99970C8CC31AC5 /* libPods-RMUniversalAlert.a */; }; 9408ECD71A1C6EED00A5A792 /* RMUniversalAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = 9408ECD61A1C6EED00A5A792 /* RMUniversalAlert.m */; }; 94318CA91A60C88F0030FA5C /* RMPopoverPresentationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 94318CA81A60C88F0030FA5C /* RMPopoverPresentationController.m */; }; 944A77DC1A1C6D14002BBBED /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 944A77DB1A1C6D14002BBBED /* main.m */; }; @@ -32,6 +32,8 @@ /* Begin PBXFileReference section */ 1F25F13F1C0362E837894225 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 4A55E5ABB1C21D6685D020A0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; + 587742414B99970C8CC31AC5 /* libPods-RMUniversalAlert.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RMUniversalAlert.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 681ADB025B57776917D40F2D /* Pods-RMUniversalAlert.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RMUniversalAlert.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RMUniversalAlert/Pods-RMUniversalAlert.debug.xcconfig"; sourceTree = ""; }; 9408ECD51A1C6EED00A5A792 /* RMUniversalAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RMUniversalAlert.h; path = ../../RMUniversalAlert.h; sourceTree = ""; }; 9408ECD61A1C6EED00A5A792 /* RMUniversalAlert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RMUniversalAlert.m; path = ../../RMUniversalAlert.m; sourceTree = ""; }; 94318CA71A60C88F0030FA5C /* RMPopoverPresentationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RMPopoverPresentationController.h; path = ../../RMPopoverPresentationController.h; sourceTree = ""; }; @@ -50,6 +52,7 @@ 944A77F41A1C6D15002BBBED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 944A77F51A1C6D15002BBBED /* RMUniversalAlertTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RMUniversalAlertTests.m; sourceTree = ""; }; AA62FB7A89B3DA8AABBA03F8 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; + E7D32E8AADDF7DCD51937DC3 /* Pods-RMUniversalAlert.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RMUniversalAlert.release.xcconfig"; path = "Pods/Target Support Files/Pods-RMUniversalAlert/Pods-RMUniversalAlert.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -57,7 +60,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 16934E8D69700F79028CB83D /* libPods.a in Frameworks */, + 26B30820B5E36FA868140C6A /* libPods-RMUniversalAlert.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -140,6 +143,7 @@ isa = PBXGroup; children = ( 1F25F13F1C0362E837894225 /* libPods.a */, + 587742414B99970C8CC31AC5 /* libPods-RMUniversalAlert.a */, ); name = Frameworks; sourceTree = ""; @@ -149,6 +153,8 @@ children = ( AA62FB7A89B3DA8AABBA03F8 /* Pods.debug.xcconfig */, 4A55E5ABB1C21D6685D020A0 /* Pods.release.xcconfig */, + 681ADB025B57776917D40F2D /* Pods-RMUniversalAlert.debug.xcconfig */, + E7D32E8AADDF7DCD51937DC3 /* Pods-RMUniversalAlert.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -160,11 +166,12 @@ isa = PBXNativeTarget; buildConfigurationList = 944A77F91A1C6D15002BBBED /* Build configuration list for PBXNativeTarget "RMUniversalAlert" */; buildPhases = ( - F49C27DB5BD33F9B37A8FFBA /* Check Pods Manifest.lock */, + F49C27DB5BD33F9B37A8FFBA /* [CP] Check Pods Manifest.lock */, 944A77D21A1C6D14002BBBED /* Sources */, 944A77D31A1C6D14002BBBED /* Frameworks */, 944A77D41A1C6D14002BBBED /* Resources */, - 43721C4A8E55A66EDAE8BC77 /* Copy Pods Resources */, + 43721C4A8E55A66EDAE8BC77 /* [CP] Copy Pods Resources */, + 592DA60F0F08D99F4B58F796 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -251,34 +258,49 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 43721C4A8E55A66EDAE8BC77 /* Copy Pods Resources */ = { + 43721C4A8E55A66EDAE8BC77 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Copy Pods Resources"; + name = "[CP] Copy Pods Resources"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RMUniversalAlert/Pods-RMUniversalAlert-resources.sh\"\n"; showEnvVarsInLog = 0; }; - F49C27DB5BD33F9B37A8FFBA /* Check Pods Manifest.lock */ = { + 592DA60F0F08D99F4B58F796 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Check Pods Manifest.lock"; + name = "[CP] Embed Pods Frameworks"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RMUniversalAlert/Pods-RMUniversalAlert-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + F49C27DB5BD33F9B37A8FFBA /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -370,7 +392,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 7.0; MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; + ONLY_ACTIVE_ARCH = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -414,19 +436,20 @@ }; 944A77FA1A1C6D15002BBBED /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = AA62FB7A89B3DA8AABBA03F8 /* Pods.debug.xcconfig */; + baseConfigurationReference = 681ADB025B57776917D40F2D /* Pods-RMUniversalAlert.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; INFOPLIST_FILE = RMUniversalAlert/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; 944A77FB1A1C6D15002BBBED /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4A55E5ABB1C21D6685D020A0 /* Pods.release.xcconfig */; + baseConfigurationReference = E7D32E8AADDF7DCD51937DC3 /* Pods-RMUniversalAlert.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; diff --git a/Tests/RMUniversalAlert/Images.xcassets/AppIcon.appiconset/Contents.json b/Tests/RMUniversalAlert/Images.xcassets/AppIcon.appiconset/Contents.json index 36d2c80..1d060ed 100644 --- a/Tests/RMUniversalAlert/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/Tests/RMUniversalAlert/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,5 +1,15 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "29x29", @@ -30,6 +40,16 @@ "size" : "60x60", "scale" : "3x" }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, { "idiom" : "ipad", "size" : "29x29", @@ -59,6 +79,11 @@ "idiom" : "ipad", "size" : "76x76", "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" } ], "info" : {