@@ -165,7 +165,7 @@ @implementation MTRDeviceController {
165
165
BOOL _shutdownPending;
166
166
os_unfair_lock _assertionLock;
167
167
168
- NSMutableSet <MTRDeviceControllerDelegateInfo *> * _delegates;
168
+ NSMutableArray <MTRDeviceControllerDelegateInfo *> * _delegates;
169
169
id <MTRDeviceControllerDelegate> _strongDelegateForSetDelegateAPI;
170
170
}
171
171
@@ -196,7 +196,7 @@ - (instancetype)initForSubclasses:(BOOL)startSuspended
196
196
197
197
_nodeIDToDeviceMap = [NSMapTable strongToWeakObjectsMapTable ];
198
198
199
- _delegates = [NSMutableSet set ];
199
+ _delegates = [NSMutableArray array ];
200
200
201
201
return self;
202
202
}
@@ -1793,7 +1793,7 @@ + (void)forceLocalhostAdvertisingOnly
1793
1793
1794
1794
#pragma mark - MTRDeviceControllerDelegate management
1795
1795
1796
- // Note these are implemented in the base class so that XPC subclass can use it as well when it
1796
+ // Note these are implemented in the base class so that XPC subclass can use it as well
1797
1797
- (void )setDeviceControllerDelegate : (id <MTRDeviceControllerDelegate>)delegate queue : (dispatch_queue_t )queue
1798
1798
{
1799
1799
@synchronized (self) {
@@ -1814,6 +1814,17 @@ - (void)setDeviceControllerDelegate:(id<MTRDeviceControllerDelegate>)delegate qu
1814
1814
- (void )addDeviceControllerDelegate : (id <MTRDeviceControllerDelegate>)delegate queue : (dispatch_queue_t )queue
1815
1815
{
1816
1816
@synchronized (self) {
1817
+ __block BOOL delegateAlreadyAdded = NO ;
1818
+ [self _iterateDelegateInfoWithBlock: ^(MTRDeviceControllerDelegateInfo * delegateInfo) {
1819
+ if (delegateInfo.delegate == delegate) {
1820
+ delegateAlreadyAdded = YES ;
1821
+ }
1822
+ }];
1823
+ if (delegateAlreadyAdded) {
1824
+ MTR_LOG (" %@ addDeviceControllerDelegate: delegate already added" , self);
1825
+ return ;
1826
+ }
1827
+
1817
1828
MTRDeviceControllerDelegateInfo * newDelegateInfo = [[MTRDeviceControllerDelegateInfo alloc ] initWithDelegate: delegate queue: queue];
1818
1829
[_delegates addObject: newDelegateInfo];
1819
1830
MTR_LOG (" %@ addDeviceControllerDelegate: added %p total %lu" , self, delegate, static_cast <unsigned long >(_delegates.count ));
@@ -1836,9 +1847,6 @@ - (void)removeDeviceControllerDelegate:(id<MTRDeviceControllerDelegate>)delegate
1836
1847
1837
1848
if (delegateInfoToRemove) {
1838
1849
[_delegates removeObject: delegateInfoToRemove];
1839
- if (_strongDelegateForSetDelegateAPI == delegate) {
1840
- _strongDelegateForSetDelegateAPI = nil ;
1841
- }
1842
1850
MTR_LOG (" %@ removeDeviceControllerDelegate: removed %p remaining %lu" , self, delegate, static_cast <unsigned long >(_delegates.count ));
1843
1851
} else {
1844
1852
MTR_LOG (" %@ removeDeviceControllerDelegate: delegate %p not found in %lu" , self, delegate, static_cast <unsigned long >(_delegates.count ));
@@ -1857,7 +1865,7 @@ - (NSUInteger)_iterateDelegateInfoWithBlock:(void (^_Nullable)(MTRDeviceControll
1857
1865
}
1858
1866
1859
1867
// Opportunistically remove defunct delegate references on every iteration
1860
- NSMutableSet * delegatesToRemove = nil ;
1868
+ NSMutableArray * delegatesToRemove = nil ;
1861
1869
for (MTRDeviceControllerDelegateInfo * delegateInfo in _delegates) {
1862
1870
id <MTRDeviceControllerDelegate> strongDelegate = delegateInfo.delegate ;
1863
1871
if (strongDelegate) {
@@ -1866,14 +1874,14 @@ - (NSUInteger)_iterateDelegateInfoWithBlock:(void (^_Nullable)(MTRDeviceControll
1866
1874
}
1867
1875
} else {
1868
1876
if (!delegatesToRemove) {
1869
- delegatesToRemove = [NSMutableSet set ];
1877
+ delegatesToRemove = [NSMutableArray array ];
1870
1878
}
1871
1879
[delegatesToRemove addObject: delegateInfo];
1872
1880
}
1873
1881
}
1874
1882
1875
1883
if (delegatesToRemove.count ) {
1876
- [_delegates minusSet : delegatesToRemove];
1884
+ [_delegates removeObjectsInArray : delegatesToRemove];
1877
1885
MTR_LOG (" %@ _iterateDelegatesWithBlock: removed %lu remaining %lu" , self, static_cast <unsigned long >(delegatesToRemove.count ), static_cast <unsigned long >(_delegates.count ));
1878
1886
}
1879
1887
0 commit comments