我对xamarin和移动设备开发还很新。我目前正在通过Firebase将geofire库迁移到xamarin.ios。我遇到了以下Objective-c代码并试图弄清楚实际上在做什么?和它的c#等价物:
@property (nonatomic, strong) NSMutableDictionary *keyEnteredObservers;
...
GFQueryLocationInfo *info = self.locationInfos[key];
[self.keyEnteredObservers enumerateKeysAndObjectsUsingBlock:^(id observerKey,
GFQueryResultBlock block,
BOOL *stop) {
dispatch_async(self.geoFire.callbackQueue, ^{ // the callbackQueue is of type @property (nonatomic, strong) dispatch_queue_t callbackQueue;
block(key, info.location);
});
}];
for callbackQueue我目前正在使用类型BlockingCollection<'Task>
非常感谢任何帮助。
答案 0 :(得分:1)
此上下文中的NSMutableDictionary.enumerateKeysAndObjectsUsingBlock
正在做两件基本事情。
它根据键过滤字典。 (Linq Where
将作为C#替代品)
字典的过滤元素可用于代码“块”,因为它是通过GCD(Grand Central Dispatch)异步执行(dispatch_async
)。因此,您已使用BlockingCollection
作为任务泵,因此将key
作为参数的字符串updateLocationInfo
和CLLocation
传递给您的任务...
注意:stop
布尔值将导致提前退出枚举器,因此C#break
作为替换,但在此上下文中不使用...
如果您仍然为观察员使用NSMutableDictionary
,则可以通过KeysForObject
进行过滤。在我的GeoFire
版本中,我使用了BlockingCollection<Action>
与任务,因此将lambdas直接添加到工作队列中。
类似的东西:
foreach (var info in keyEnteredObservers.KeysForObject(firebaseHandle))
{
var nonCapturedLocation = info.location.Copy(); // location = CLLocation, do not capture entire dictionary by ref in lambda
callbackQueue.Add(() =>
{
GFQueryResultBlock(key, nonCapturedLocation);
});
}