@@ -79,6 +79,10 @@ CHIP_ERROR Start(id<MTRCommissionableBrowserDelegate> delegate, MTRDeviceControl
79
79
VerifyOrReturnError (mDispatchQueue == nil , CHIP_ERROR_INCORRECT_STATE);
80
80
VerifyOrReturnError (mDiscoveredResults == nil , CHIP_ERROR_INCORRECT_STATE);
81
81
82
+ VerifyOrReturnError (delegate != nil , CHIP_ERROR_INVALID_ARGUMENT);
83
+ VerifyOrReturnError (controller != nil , CHIP_ERROR_INVALID_ARGUMENT);
84
+ VerifyOrReturnError (queue != nil , CHIP_ERROR_INVALID_ARGUMENT);
85
+
82
86
mDelegate = delegate;
83
87
mController = controller;
84
88
mDispatchQueue = queue;
@@ -173,6 +177,11 @@ void OnNodeDiscovered(const DiscoveredNodeData & nodeData) override
173
177
{
174
178
assertChipStackLockedByCurrentThread ();
175
179
180
+ // Copy delegate and controller to the stack to avoid capturing `this` in the dispatch_async
181
+ id <MTRCommissionableBrowserDelegate> delegate = mDelegate ;
182
+ MTRDeviceController * controller = mController ;
183
+ VerifyOrReturn (delegate != nil && controller != nil );
184
+
176
185
if (!nodeData.Is <CommissionNodeData>()) {
177
186
// not commissionable/commissioners node
178
187
return ;
@@ -207,13 +216,10 @@ void OnNodeDiscovered(const DiscoveredNodeData & nodeData) override
207
216
break ;
208
217
}
209
218
}
210
-
211
- if (!shouldDispatchToDelegate) {
212
- return ;
213
- }
219
+ VerifyOrReturn (shouldDispatchToDelegate);
214
220
215
221
dispatch_async (mDispatchQueue , ^{
216
- [mDelegate controller: mController didFindCommissionableDevice: result];
222
+ [delegate controller: controller didFindCommissionableDevice: result];
217
223
});
218
224
}
219
225
@@ -245,9 +251,10 @@ void OnBrowseRemove(DnssdService service) override
245
251
{
246
252
assertChipStackLockedByCurrentThread ();
247
253
248
- VerifyOrReturn (mDelegate != nil );
249
- VerifyOrReturn (mController != nil );
250
- VerifyOrReturn (mDispatchQueue != nil );
254
+ // Copy delegate and controller to the stack to avoid capturing `this` in the dispatch_async
255
+ id <MTRCommissionableBrowserDelegate> delegate = mDelegate ;
256
+ MTRDeviceController * controller = mController ;
257
+ VerifyOrReturn (delegate != nil && controller != nil );
251
258
252
259
MATTER_LOG_METRIC (kMetricOnNetworkDevicesRemoved , ++mOnNetworkDevicesRemoved );
253
260
@@ -278,7 +285,7 @@ void OnBrowseRemove(DnssdService service) override
278
285
// resolving it), so don't bother notifying about the removal either.
279
286
if (result.instanceName != nil ) {
280
287
dispatch_async (mDispatchQueue , ^{
281
- [mDelegate controller: mController didRemoveCommissionableDevice: result];
288
+ [delegate controller: controller didRemoveCommissionableDevice: result];
282
289
});
283
290
}
284
291
@@ -298,7 +305,11 @@ void OnBrowseStop(CHIP_ERROR error) override
298
305
void OnBleScanAdd (BLE_CONNECTION_OBJECT connObj, const ChipBLEDeviceIdentificationInfo & info) override
299
306
{
300
307
assertChipStackLockedByCurrentThread ();
301
- VerifyOrReturn (mDelegate != nil );
308
+
309
+ // Copy delegate and controller to the stack to avoid capturing `this` in the dispatch_async
310
+ id <MTRCommissionableBrowserDelegate> delegate = mDelegate ;
311
+ MTRDeviceController * controller = mController ;
312
+ VerifyOrReturn (delegate != nil && controller != nil );
302
313
303
314
auto result = [[MTRCommissionableBrowserResult alloc ] init ];
304
315
result.instanceName = [NSString stringWithUTF8String: kBleKey ];
@@ -315,14 +326,18 @@ void OnBleScanAdd(BLE_CONNECTION_OBJECT connObj, const ChipBLEDeviceIdentificati
315
326
mDiscoveredResults [key] = result;
316
327
317
328
dispatch_async (mDispatchQueue , ^{
318
- [mDelegate controller: mController didFindCommissionableDevice: result];
329
+ [delegate controller: controller didFindCommissionableDevice: result];
319
330
});
320
331
}
321
332
322
333
void OnBleScanRemove (BLE_CONNECTION_OBJECT connObj) override
323
334
{
324
335
assertChipStackLockedByCurrentThread ();
325
- VerifyOrReturn (mDelegate != nil );
336
+
337
+ // Copy delegate and controller to the stack to avoid capturing `this` in the dispatch_async
338
+ id <MTRCommissionableBrowserDelegate> delegate = mDelegate ;
339
+ MTRDeviceController * controller = mController ;
340
+ VerifyOrReturn (delegate != nil && controller != nil );
326
341
327
342
auto key = [NSString stringWithFormat: @" %@ " , connObj];
328
343
if ([mDiscoveredResults objectForKey: key] == nil ) {
@@ -336,12 +351,13 @@ void OnBleScanRemove(BLE_CONNECTION_OBJECT connObj) override
336
351
MATTER_LOG_METRIC (kMetricBLEDevicesRemoved , ++mBLEDevicesRemoved );
337
352
338
353
dispatch_async (mDispatchQueue , ^{
339
- [mDelegate controller: mController didRemoveCommissionableDevice: result];
354
+ [delegate controller: controller didRemoveCommissionableDevice: result];
340
355
});
341
356
}
342
357
343
358
void OnBleScanStopped () override
344
359
{
360
+ assertChipStackLockedByCurrentThread ();
345
361
mBleScannerDelegateOwner = nil ;
346
362
}
347
363
@@ -350,22 +366,21 @@ void OnBleScanStopped() override
350
366
private:
351
367
dispatch_queue_t mDispatchQueue ;
352
368
id <MTRCommissionableBrowserDelegate> mDelegate ;
353
- MTRDeviceController * mController ;
369
+ MTRDeviceController * __weak mController ;
354
370
NSMutableDictionary <NSString *, MTRCommissionableBrowserResult *> * mDiscoveredResults ;
355
371
int32_t mOnNetworkDevicesAdded ;
356
372
int32_t mOnNetworkDevicesRemoved ;
357
373
int32_t mBLEDevicesAdded ;
358
374
int32_t mBLEDevicesRemoved ;
359
375
};
360
376
361
- @interface MTRCommissionableBrowser ()
362
- @property ( strong , nonatomic ) dispatch_queue_t queue ;
363
- @property ( nonatomic , readonly ) id <MTRCommissionableBrowserDelegate> delegate ;
364
- @property ( nonatomic , readonly ) MTRDeviceController * controller ;
365
- @property (unsafe_unretained, nonatomic ) CommissionableBrowserInternal browser ;
366
- @end
377
+ @implementation MTRCommissionableBrowser {
378
+ id <MTRCommissionableBrowserDelegate> _delegate ;
379
+ dispatch_queue_t _queue ;
380
+ MTRDeviceController * __weak _controller ;
381
+ CommissionableBrowserInternal _browser ;
382
+ }
367
383
368
- @implementation MTRCommissionableBrowser
369
384
- (instancetype )initWithDelegate : (id <MTRCommissionableBrowserDelegate>)delegate
370
385
controller : (MTRDeviceController *)controller
371
386
queue : (dispatch_queue_t )queue
0 commit comments