ソースを参照

ios - change store to have NSMapTable instead of NSMutableDictionary

Ran Greenberg 7 年 前
コミット
a156e4764a

+ 1
- 1
ios/RNNBridgeModule.m ファイルの表示

39
 	[self assertReady];
39
 	[self assertReady];
40
 	UIViewController *vc = [[RNN instance].store findContainerForId:containerId];
40
 	UIViewController *vc = [[RNN instance].store findContainerForId:containerId];
41
 	
41
 	
42
-	[[vc navigationController] popViewControllerAnimated:true];
42
+	[[vc navigationController] popViewControllerAnimated:YES];
43
 	[[RNN instance].store removeContainer:containerId];
43
 	[[RNN instance].store removeContainer:containerId];
44
 }
44
 }
45
 
45
 

+ 4
- 6
ios/RNNStore.m ファイルの表示

10
 
10
 
11
 @interface RNNStore ()
11
 @interface RNNStore ()
12
 
12
 
13
-@property NSMutableDictionary *containerStore;
13
+@property NSMapTable *containerStore;
14
 
14
 
15
 @end
15
 @end
16
 
16
 
19
 
19
 
20
 -(instancetype)init {
20
 -(instancetype)init {
21
 	self = [super init];
21
 	self = [super init];
22
-	self.containerStore = [NSMutableDictionary new];
23
-	
22
+	self.containerStore = [NSMapTable strongToWeakObjectsMapTable];
24
 	return self;
23
 	return self;
25
 }
24
 }
26
 
25
 
27
 
26
 
28
 -(UIViewController *)findContainerForId:(NSString *)containerId {
27
 -(UIViewController *)findContainerForId:(NSString *)containerId {
29
-	return [self.containerStore valueForKey:containerId];
28
+	return [self.containerStore objectForKey:containerId];
29
+	
30
 }
30
 }
31
 
31
 
32
 
32
 
46
 }
46
 }
47
 
47
 
48
 
48
 
49
-
50
-
51
 @end
49
 @end

+ 1
- 1
playground/ios/playground.xcodeproj/project.pbxproj ファイルの表示

295
 			isa = PBXGroup;
295
 			isa = PBXGroup;
296
 			children = (
296
 			children = (
297
 				26070FCF1E4B8B9D003EC8B9 /* RNNControllerFactoryTest.m */,
297
 				26070FCF1E4B8B9D003EC8B9 /* RNNControllerFactoryTest.m */,
298
-				00E356F01AD99517003FC87E /* Supporting Files */,
299
 				268692841E50572700E2C612 /* RNNStoreTest.m */,
298
 				268692841E50572700E2C612 /* RNNStoreTest.m */,
299
+				00E356F01AD99517003FC87E /* Supporting Files */,
300
 			);
300
 			);
301
 			path = playgroundTests;
301
 			path = playgroundTests;
302
 			sourceTree = "<group>";
302
 			sourceTree = "<group>";

+ 18
- 3
playground/ios/playgroundTests/RNNStoreTest.m ファイルの表示

18
 @implementation RNNStoreTest
18
 @implementation RNNStoreTest
19
 
19
 
20
 - (void)setUp {
20
 - (void)setUp {
21
-    [super setUp];
21
+	[super setUp];
22
 	
22
 	
23
 	self.store = [RNNStore new];
23
 	self.store = [RNNStore new];
24
 }
24
 }
43
 - (void)testSetContainer_setNilContainerId {
43
 - (void)testSetContainer_setNilContainerId {
44
 	NSString *containerId1 = nil;
44
 	NSString *containerId1 = nil;
45
 	UIViewController *vc1 = [UIViewController new];
45
 	UIViewController *vc1 = [UIViewController new];
46
-	XCTAssertThrows([self.store setContainer:vc1 containerId:containerId1]);
46
+	[self.store setContainer:vc1 containerId:containerId1];
47
 	XCTAssertNil([self.store findContainerForId:containerId1]);
47
 	XCTAssertNil([self.store findContainerForId:containerId1]);
48
 	
48
 	
49
 }
49
 }
71
 	XCTAssertEqualObjects(vc1, ans);
71
 	XCTAssertEqualObjects(vc1, ans);
72
 	
72
 	
73
 	[self.store removeContainer:containerId1];
73
 	[self.store removeContainer:containerId1];
74
-	
75
 	XCTAssertNil([self.store findContainerForId:containerId1]);
74
 	XCTAssertNil([self.store findContainerForId:containerId1]);
76
 }
75
 }
77
 
76
 
77
+-(void)testPopWillRemoveVcFromStore {
78
+	NSString *vcId = @"cnt_vc_2";
79
+	
80
+	[self setContainerAndRelease:vcId];
81
+	
82
+	
83
+	XCTAssertNil([self.store findContainerForId:vcId]); // PASS
84
+}
78
 
85
 
86
+-(void) setContainerAndRelease:(NSString*)vcId {
87
+	@autoreleasepool {
88
+		UIViewController *vc2 = [UIViewController new];
89
+		[self.store setContainer:vc2 containerId:vcId];
90
+		
91
+		XCTAssertNotNil([self.store findContainerForId:vcId]); // PASS
92
+	}
93
+}
79
 
94
 
80
 @end
95
 @end

+ 18
- 0
playground/src/containers/SimpleScreen.js ファイルの表示

7
   constructor(props) {
7
   constructor(props) {
8
     super(props);
8
     super(props);
9
     this.onClickPop = this.onClickPop.bind(this);
9
     this.onClickPop = this.onClickPop.bind(this);
10
+    this.onClickPush = this.onClickPush.bind(this);
10
   }
11
   }
11
 
12
 
12
   render() {
13
   render() {
13
     return (
14
     return (
14
       <View style={styles.root}>
15
       <View style={styles.root}>
15
         <Text style={styles.h1}>{this.props.text || 'Simple Screen'}</Text>
16
         <Text style={styles.h1}>{this.props.text || 'Simple Screen'}</Text>
17
+        <Text style={styles.h2}>{this.props.stackPosition}</Text>
16
         {this.renderTextFromFunctionInProps()}
18
         {this.renderTextFromFunctionInProps()}
19
+        <Button title="Push" onPress={this.onClickPush} />
17
         <Button title="Pop" onPress={this.onClickPop} />
20
         <Button title="Pop" onPress={this.onClickPop} />
18
       </View>
21
       </View>
19
     );
22
     );
31
   onClickPop() {
34
   onClickPop() {
32
     Navigation.on(this.props.id).pop();
35
     Navigation.on(this.props.id).pop();
33
   }
36
   }
37
+  
38
+  onClickPush() {
39
+    Navigation.on(this.props.id).push({
40
+      name: 'navigation.playground.SimpleScreen',
41
+      passProps: {
42
+        stackPosition: this.props.stackPosition + 1,
43
+      }
44
+    });
45
+  }
46
+
34
 }
47
 }
35
 export default SimpleScreen;
48
 export default SimpleScreen;
36
 
49
 
45
     fontSize: 24,
58
     fontSize: 24,
46
     textAlign: 'center',
59
     textAlign: 'center',
47
     margin: 10
60
     margin: 10
61
+  },
62
+  h2: {
63
+    fontSize: 12,
64
+    textAlign: 'center',
65
+    margin: 10
48
   }
66
   }
49
 };
67
 };

+ 8
- 1
playground/src/containers/WelcomeScreen.js ファイルの表示

7
   constructor(props) {
7
   constructor(props) {
8
     super(props);
8
     super(props);
9
     this.onClickPush = this.onClickPush.bind(this);
9
     this.onClickPush = this.onClickPush.bind(this);
10
+    this.onShowModal = this.onShowModal.bind(this);
10
   }
11
   }
11
 
12
 
12
   render() {
13
   render() {
17
         <Button title="Switch to app with side menus" onPress={this.onClickSwitchToSideMenus} />
18
         <Button title="Switch to app with side menus" onPress={this.onClickSwitchToSideMenus} />
18
         <Button title="Switch to lifecycle screen" onPress={this.onClickLifecycleScreen} />
19
         <Button title="Switch to lifecycle screen" onPress={this.onClickLifecycleScreen} />
19
         <Button title="Push" onPress={this.onClickPush} />
20
         <Button title="Push" onPress={this.onClickPush} />
21
+        <Button title="Show Modal" onPress={this.onClickPush} />
20
         <Text style={styles.footer}>{`this.props.id = ${this.props.id}`}</Text>
22
         <Text style={styles.footer}>{`this.props.id = ${this.props.id}`}</Text>
21
       </View>
23
       </View>
22
     );
24
     );
90
     Navigation.on(this.props.id).push({
92
     Navigation.on(this.props.id).push({
91
       name: 'navigation.playground.SimpleScreen',
93
       name: 'navigation.playground.SimpleScreen',
92
       passProps: {
94
       passProps: {
93
-        text: 'Pushed screen'
95
+        text: 'Pushed screen',
96
+        stackPosition: 1
94
       }
97
       }
95
     });
98
     });
96
   }
99
   }
102
       }
105
       }
103
     });
106
     });
104
   }
107
   }
108
+  
109
+  onShowModal() {
110
+    Navigation.on(this.props.id).show
111
+  }
105
 }
112
 }
106
 
113
 
107
 export default WelcomeScreen;
114
 export default WelcomeScreen;