Skip to content

Commit 9827bc7

Browse files
committed
Fixes memory leak when unsubscribing
1 parent 2ae3b36 commit 9827bc7

File tree

5 files changed

+47
-19
lines changed

5 files changed

+47
-19
lines changed

caravel-test.xcodeproj/project.pbxproj

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@
3838
A79762951B199541006D94CB /* event_data.js in Resources */ = {isa = PBXBuildFile; fileRef = A79762941B199541006D94CB /* event_data.js */; };
3939
A79762971B19954A006D94CB /* event_data.html in Resources */ = {isa = PBXBuildFile; fileRef = A79762961B19954A006D94CB /* event_data.html */; };
4040
A7AC9F2A1B349BB40041EB0B /* caravel.min.js in Resources */ = {isa = PBXBuildFile; fileRef = A7AC9F291B349BB40041EB0B /* caravel.min.js */; };
41+
A7BC5DC41C09507100C0230A /* Caravel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7BC5DC31C09507100C0230A /* Caravel.framework */; };
42+
A7BC5DC51C09507100C0230A /* Caravel.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A7BC5DC31C09507100C0230A /* Caravel.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
4143
A7C869061B18CEF30070AF5A /* basic_triggering.html in Resources */ = {isa = PBXBuildFile; fileRef = A7C869051B18CEF30070AF5A /* basic_triggering.html */; };
4244
A7C869081B18CF450070AF5A /* basic_triggering.js in Resources */ = {isa = PBXBuildFile; fileRef = A7C869071B18CF450070AF5A /* basic_triggering.js */; };
4345
A7DC081B1B18C73500D98DA5 /* BasicTriggeringController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7DC081A1B18C73500D98DA5 /* BasicTriggeringController.swift */; };
44-
A7EE0BA71BEC423E00D0925C /* Caravel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7EE0BA61BEC423E00D0925C /* Caravel.framework */; };
45-
A7EE0BA81BEC423E00D0925C /* Caravel.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A7EE0BA61BEC423E00D0925C /* Caravel.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
4646
A7F1DE291B18045C001E9B94 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7F1DE281B18045C001E9B94 /* AppDelegate.swift */; };
4747
A7F1DE2B1B18045C001E9B94 /* MainController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7F1DE2A1B18045C001E9B94 /* MainController.swift */; };
4848
A7F1DE2E1B18045C001E9B94 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A7F1DE2C1B18045C001E9B94 /* Main.storyboard */; };
@@ -62,13 +62,13 @@
6262
/* End PBXContainerItemProxy section */
6363

6464
/* Begin PBXCopyFilesBuildPhase section */
65-
A7EE0BA91BEC423E00D0925C /* Embed Frameworks */ = {
65+
A7BC5DC61C09507100C0230A /* Embed Frameworks */ = {
6666
isa = PBXCopyFilesBuildPhase;
6767
buildActionMask = 2147483647;
6868
dstPath = "";
6969
dstSubfolderSpec = 10;
7070
files = (
71-
A7EE0BA81BEC423E00D0925C /* Caravel.framework in Embed Frameworks */,
71+
A7BC5DC51C09507100C0230A /* Caravel.framework in Embed Frameworks */,
7272
);
7373
name = "Embed Frameworks";
7474
runOnlyForDeploymentPostprocessing = 0;
@@ -107,10 +107,10 @@
107107
A79762941B199541006D94CB /* event_data.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = event_data.js; path = js/event_data.js; sourceTree = "<group>"; };
108108
A79762961B19954A006D94CB /* event_data.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = event_data.html; path = html/event_data.html; sourceTree = "<group>"; };
109109
A7AC9F291B349BB40041EB0B /* caravel.min.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = caravel.min.js; path = caravel/js/caravel.min.js; sourceTree = SOURCE_ROOT; };
110+
A7BC5DC31C09507100C0230A /* Caravel.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = Caravel.framework; path = "/Users/acadet/Library/Developer/Xcode/DerivedData/caravel-dlpamqduufdwsvhblzaeqpmtdyag/Build/Products/Debug-iphoneos/Caravel.framework"; sourceTree = "<absolute>"; };
110111
A7C869051B18CEF30070AF5A /* basic_triggering.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = basic_triggering.html; path = html/basic_triggering.html; sourceTree = "<group>"; };
111112
A7C869071B18CF450070AF5A /* basic_triggering.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = basic_triggering.js; path = js/basic_triggering.js; sourceTree = "<group>"; };
112113
A7DC081A1B18C73500D98DA5 /* BasicTriggeringController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicTriggeringController.swift; sourceTree = "<group>"; };
113-
A7EE0BA61BEC423E00D0925C /* Caravel.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = Caravel.framework; path = "/Users/acadet/Library/Developer/Xcode/DerivedData/caravel-gxizvdjjntycpgaiopgmjthvbutx/Build/Products/Debug-iphoneos/Caravel.framework"; sourceTree = "<absolute>"; };
114114
A7F1DE231B18045C001E9B94 /* caravel-test.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "caravel-test.app"; sourceTree = BUILT_PRODUCTS_DIR; };
115115
A7F1DE271B18045C001E9B94 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
116116
A7F1DE281B18045C001E9B94 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@@ -128,7 +128,7 @@
128128
isa = PBXFrameworksBuildPhase;
129129
buildActionMask = 2147483647;
130130
files = (
131-
A7EE0BA71BEC423E00D0925C /* Caravel.framework in Frameworks */,
131+
A7BC5DC41C09507100C0230A /* Caravel.framework in Frameworks */,
132132
);
133133
runOnlyForDeploymentPostprocessing = 0;
134134
};
@@ -182,7 +182,7 @@
182182
A7F1DE1A1B18045C001E9B94 = {
183183
isa = PBXGroup;
184184
children = (
185-
A7EE0BA61BEC423E00D0925C /* Caravel.framework */,
185+
A7BC5DC31C09507100C0230A /* Caravel.framework */,
186186
A7F1DE251B18045C001E9B94 /* caravel-test */,
187187
A7F1DE3B1B18045C001E9B94 /* caravel-testTests */,
188188
A7F1DE241B18045C001E9B94 /* Products */,
@@ -259,7 +259,7 @@
259259
A7F1DE1F1B18045C001E9B94 /* Sources */,
260260
A7F1DE201B18045C001E9B94 /* Frameworks */,
261261
A7F1DE211B18045C001E9B94 /* Resources */,
262-
A7EE0BA91BEC423E00D0925C /* Embed Frameworks */,
262+
A7BC5DC61C09507100C0230A /* Embed Frameworks */,
263263
);
264264
buildRules = (
265265
);
@@ -518,6 +518,7 @@
518518
FRAMEWORK_SEARCH_PATHS = (
519519
"$(inherited)",
520520
"/Users/acadet/Documents/workspace/swift/caravel/build/Debug-iphoneos",
521+
"$(PROJECT_DIR)/build/Debug-iphoneos",
521522
);
522523
INFOPLIST_FILE = "caravel-test/Info.plist";
523524
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
@@ -534,6 +535,7 @@
534535
FRAMEWORK_SEARCH_PATHS = (
535536
"$(inherited)",
536537
"/Users/acadet/Documents/workspace/swift/caravel/build/Debug-iphoneos",
538+
"$(PROJECT_DIR)/build/Debug-iphoneos",
537539
);
538540
INFOPLIST_FILE = "caravel-test/Info.plist";
539541
IPHONEOS_DEPLOYMENT_TARGET = 8.1;

caravel-test/Base.lproj/Main.storyboard

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9059" systemVersion="15A284" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="vXZ-lx-hvc">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="vXZ-lx-hvc">
33
<dependencies>
44
<deployment identifier="iOS"/>
5-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9049"/>
5+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
66
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
77
</dependencies>
88
<scenes>

caravel-test/UnregistrationController.swift

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,29 @@ import Caravel
44

55
class UnregistrationController: UIViewController {
66

7+
class WeakWrapper {
8+
weak var wrapped: UnregistrationController?
9+
10+
init(wrapped: UnregistrationController) {
11+
self.wrapped = wrapped
12+
}
13+
14+
func unsubscribe() {
15+
self.wrapped?.unsubscribe()
16+
}
17+
}
18+
719
@IBOutlet weak var webView: UIWebView!
820
private weak var bus: EventBus?
21+
private weak var timer: NSTimer?
922

1023
override func viewDidLoad() {
1124
Caravel.getDefault(self, webView: webView, whenReady: { bus in
1225
self.bus = bus
1326

1427
bus.registerOnMain("Whazup?") { _, _ in
1528
bus.post("Bye")
16-
NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: "unsubscribe", userInfo: nil, repeats: false)
29+
self.timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: "unsubscribe", userInfo: nil, repeats: false)
1730
}
1831

1932
bus.register("Still around?") { name, _ in
@@ -26,7 +39,20 @@ class UnregistrationController: UIViewController {
2639
webView.loadRequest(NSURLRequest(URL: NSBundle.mainBundle().URLForResource("unregistration", withExtension: "html")!))
2740
}
2841

42+
override func viewWillDisappear(animated: Bool) {
43+
super.viewWillDisappear(animated)
44+
45+
// Clean webview before exiting
46+
webView.loadHTMLString("", baseURL: nil)
47+
webView.delegate = nil
48+
webView.removeFromSuperview()
49+
}
50+
2951
func unsubscribe() {
30-
bus!.unregister(self)
52+
self.bus!.unregister()
53+
dispatch_async(dispatch_get_main_queue()) {
54+
self.timer?.invalidate()
55+
self.timer = nil
56+
}
3157
}
3258
}

caravel/EventBus.swift

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,11 @@ public class EventBus: NSObject, UIWebViewDelegate {
210210
* Unregisters subscriber from bus
211211
* @param subscriber Should be the same one than provided when registering.
212212
*/
213-
public func unregister(subscriber: AnyObject) {
214-
if subscriber.hash == self.reference?.hash {
215-
self.dispatcher!.deleteBus(self)
216-
UIWebViewDelegateMediator.unsubscribe(self.webView!, subscriber: self)
217-
self.reference = nil
218-
self.webView = nil
219-
}
213+
public func unregister() {
214+
self.dispatcher!.deleteBus(self)
215+
UIWebViewDelegateMediator.unsubscribe(self.webView!, subscriber: self)
216+
self.dispatcher = nil
217+
self.reference = nil
218+
self.webView = nil
220219
}
221220
}

caravel/internal/UIWebViewDelegateMediator.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ internal class UIWebViewDelegateMediator: NSObject, UIWebViewDelegate {
6767
a.removeAtIndex(i)
6868
if a.count == 0 {
6969
singleton.webViewSubscribers.removeValueForKey(key)
70+
webView.delegate = nil
7071
}
7172
return
7273
}

0 commit comments

Comments
 (0)