1414@implementation NSObject (PYThemeExtension)
1515
1616/* * 主题颜色池 */
17- static NSMutableArray <NSDictionary *> *_themeColorPool;
17+ static NSMutableArray <NSMapTable *> *_themeColorPool;
1818/* * 当前主题色 */
1919static UIColor *_currentThemeColor;
2020
@@ -169,54 +169,80 @@ - (void)py_addToThemeColorPoolWithSelector:(SEL)selector objects:(NSArray *)obje
169169 if ([self isMemberOfClass: appearanceClass]) return ;
170170 // 键:对象地址+方法名 值:对象
171171 NSString *pointSelectorString = [NSString stringWithFormat: @" %p %@ " , self , NSStringFromSelector (selector)];
172- NSDictionary *dic = @{ pointSelectorString : self,
173- PYTHEME_COLOR_ARGS_KEY : objects };
172+ // 采用NSMapTable存储对象,使用弱引用
173+ NSMapTable *mapTable = [NSMapTable mapTableWithKeyOptions: NSMapTableCopyIn valueOptions: NSMapTableWeakMemory ];
174+ [mapTable setObject: self forKey: pointSelectorString];
175+ [mapTable setObject: objects forKey: PYTHEME_COLOR_ARGS_KEY];
174176 // 判断是否已经在主题色池中
175- if (![[self themeColorPool ] containsObject: dic]) { // 不在主题色池中
176- [[self themeColorPool ] addObject: dic];
177- if (_currentThemeColor) { // 已经设置主题色,直接设置
178- [self py_performSelector: selector withObjects: objects];
177+ for (NSMapTable *subMapTable in [[self themeColorPool ] copy ]) {
178+ if ([[subMapTable description ] isEqualToString: [mapTable description ]]) { // 存在,直接返回
179+ return ;
179180 }
180181 }
182+ // 不存在,添加主题色池中
183+ [[self themeColorPool ] addObject: mapTable];
184+ if (_currentThemeColor) { // 已经设置主题色,直接设置
185+ [self py_performSelector: selector withObjects: objects];
186+ }
181187}
182188
183189/* *
184- * 添加到主题色池
185- * propertyName : 属性名
190+ * 从主题色池移除
191+ * selector : 执行方法
186192 */
187- - (void )py_addToThemeColorPool : ( NSString *) propertyName
193+ - (void )py_removeFromThemeColorPoolWithSelector : ( SEL ) selector
188194{
189195 // 如果对象为_UIAppearance,直接返回
190196 Class appearanceClass = NSClassFromString (@" _UIAppearance" );
191197 if ([self isMemberOfClass: appearanceClass]) return ;
192- // 键:对象地址+属性名 值:对象
193- NSString *pointString = [NSString stringWithFormat: @" %p %@ " , self , propertyName];
194- NSDictionary *dic = @{ pointString : self };
195- // 判断是否已经在主题色中
196- if (![[self themeColorPool ] containsObject: dic]) { // 不在主题色池中
197- [[self themeColorPool ] addObject: dic];
198- if (_currentThemeColor) { // 已经设置主题色,直接设置
199- [self setValue: _currentThemeColor forKey: propertyName];
200- }
201- }
202- // 遍历主题色池(移除应该被回收的对象)
203- for (NSDictionary *dict in [[self themeColorPool ] copy ]) {
198+
199+ // 键:对象地址+方法名 值:对象
200+ NSString *pointSelectorString = [NSString stringWithFormat: @" %p %@ " , self , NSStringFromSelector (selector)];
201+ // 判断是否已经在主题色池中
202+ for (NSMapTable *subMapTable in [[self themeColorPool ] copy ]) {
204203 // 取出key
205204 NSString *objectKey = nil ;
206- for (NSString *key in [dict allKeys ]) {
205+ // 获取mapTable中所有key
206+ NSEnumerator *enumerator = [subMapTable keyEnumerator ];
207+ NSString *key;
208+ while (key = [enumerator nextObject ]) {
207209 if (![key isEqualToString: PYTHEME_COLOR_ARGS_KEY]) {
208210 objectKey = key;
209211 break ;
210212 }
211213 }
212- // 取出对象
213- id object = [dict valueForKey: objectKey];
214- // 取出对象的引用计数
215- NSInteger retainCount = [[object valueForKey: @" retainCount" ] integerValue ];
216- if (retainCount == 2 ) { // 对象应该被回收了
217- [[self themeColorPool ] removeObject: dict];
214+ if ([objectKey isEqualToString: pointSelectorString]) { // 存在,移除
215+ [[self themeColorPool ] removeObject: subMapTable];
216+ return ;
217+ }
218+ }
219+ }
220+
221+ /* *
222+ * 添加到主题色池
223+ * propertyName : 属性名
224+ */
225+ - (void )py_addToThemeColorPool : (NSString *)propertyName
226+ {
227+ // 如果对象为_UIAppearance,直接返回
228+ Class appearanceClass = NSClassFromString (@" _UIAppearance" );
229+ if ([self isMemberOfClass: appearanceClass]) return ;
230+ // 键:对象地址+属性名 值:对象
231+ NSString *pointString = [NSString stringWithFormat: @" %p %@ " , self , propertyName];
232+ // 采用NSMapTable存储对象,使用弱引用
233+ NSMapTable *mapTable = [NSMapTable mapTableWithKeyOptions: NSMapTableCopyIn valueOptions: NSMapTableWeakMemory ];
234+ [mapTable setObject: self forKey: pointString];
235+ // 判断是否已经在主题色池中
236+ for (NSMapTable *subMapTable in [[self themeColorPool ] copy ]) {
237+ if ([[subMapTable description ] isEqualToString: [mapTable description ]]) { // 存在,直接返回
238+ return ;
218239 }
219240 }
241+ // 不存在,添加主题色池中
242+ [[self themeColorPool ] addObject: mapTable];
243+ if (_currentThemeColor) { // 已经设置主题色,直接设置
244+ [self setValue: _currentThemeColor forKey: propertyName];
245+ }
220246}
221247
222248/* *
@@ -231,10 +257,14 @@ - (void)py_removeFromThemeColorPool:(NSString *)propertyName
231257
232258 // 键:对象地址+属性名 值:对象
233259 NSString *pointString = [NSString stringWithFormat: @" %p %@ " , self , propertyName];
234- NSDictionary *dic = @{ pointString : self };
235260 // 判断是否已经在主题色池中
236- if ([[self themeColorPool ] containsObject: dic]) { // 在主题色池中
237- [[self themeColorPool ] removeObject: dic];
261+ for (NSMapTable *subMapTable in [[self themeColorPool ] copy ]) {
262+ // 获取mapTable中所有key
263+ NSEnumerator *enumerator = [subMapTable keyEnumerator ];
264+ if ([[enumerator nextObject ] isEqualToString: pointString]) { // 存在,移除
265+ [[self themeColorPool ] removeObject: subMapTable];
266+ return ;
267+ }
238268 }
239269}
240270
@@ -246,20 +276,26 @@ - (void)py_setThemeColor:(UIColor *)color
246276{
247277 _currentThemeColor = color;
248278 // 遍历缓主题池,设置统一主题色
249- for (NSDictionary *dict in [_themeColorPool copy ]) {
279+ for (NSMapTable *mapTable in [_themeColorPool copy ]) {
250280 // 取出key
251281 NSString *objectKey = nil ;
252- for (NSString *key in [dict allKeys ]) {
282+ // 获取mapTable中所有key
283+ NSEnumerator *enumerator = [mapTable keyEnumerator ];
284+ NSString *key;
285+ while (key = [enumerator nextObject ]) {
253286 if (![key isEqualToString: PYTHEME_COLOR_ARGS_KEY]) {
254287 objectKey = key;
255288 break ;
256289 }
257290 }
291+ if (!key) { // 如果key为空,则mapTable 为空,移除mapTable
292+ [_themeColorPool removeObject: mapTable];
293+ }
258294 // 取出对象
259- id object = [dict valueForKey : objectKey];
295+ id object = [mapTable objectForKey : objectKey];
260296 if ([objectKey containsString: @" :" ]) { // 方法
261297 // 取出参数
262- NSArray *args = dict[ PYTHEME_COLOR_ARGS_KEY];
298+ NSArray *args = [mapTable objectForKey: PYTHEME_COLOR_ARGS_KEY];
263299 // 取出方法
264300 NSString *selectorName = [objectKey substringFromIndex: [[NSString stringWithFormat: @" %p " , object] length ]];
265301 SEL selector = NSSelectorFromString (selectorName);
@@ -295,13 +331,6 @@ - (void)py_addToThemeImagePool
295331 if (![[self themeImagePool ] containsObject: self ]) { // 不在主题图片池中
296332 [[self themeImagePool ] addObject: self ];
297333 }
298- // 遍历主题图片池(移除应该被回收的对象)
299- for (id object in [self themeImagePool ]) {
300- NSInteger retainCount = [[object valueForKey: @" retainCount" ] integerValue ];
301- if (retainCount == 2 ) { // 对象应该被回收了
302- [[self themeImagePool ] removeObject: self ];
303- }
304- }
305334}
306335
307336/* * 从主题图片池中移除 */
0 commit comments