我需要同步在主队列上调度一个块.我不知道我目前是在主线程上运行还是不运行.天真的解决方案看起来像这样:
dispatch_sync(dispatch_get_main_queue(), block);
Run Code Online (Sandbox Code Playgroud)
但是如果我当前在主队列上运行的块中,则此调用会产生死锁.(同步调度等待块完成,但块甚至没有开始运行,因为我们正在等待当前块完成.)
显而易见的下一步是检查当前队列:
if (dispatch_get_current_queue() == dispatch_get_main_queue()) {
block();
} else {
dispatch_sync(dispatch_get_main_queue(), block);
}
Run Code Online (Sandbox Code Playgroud)
这有效,但很难看.在我至少将它隐藏在一些自定义功能之前,是不是有更好的解决方案来解决这个问题?我强调我不能异步调度块 - 应用程序处于异步调度块将"执行得太晚"的情况.
如何使块同步执行,或使函数在return语句之前等待处理程序,以便数据可以从块传回?
-(id)performRequest:(id)args
{
__block NSData *data = nil;
[xyzclass requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
data = [NSData dataWithData:responseData];
}];
return data;
}
Run Code Online (Sandbox Code Playgroud) 这是我的代码:
var userRef = new Firebase("https://awesome.firebaseio.com/users/");
var tokenRef = userRef.child(key+'/tokens');
tokenRef.once('value', function(snapshot){
var userTokenSync = $firebase(tokenRef);
var userTokens = userTokenSync.$asArray();
console.log(userTokens);
console.log(userTokens[0]);
for(var i=0, len = userTokens.length; i < len; i++) {
console.log(userTokens[i]);
}
console.log('done');
})
Run Code Online (Sandbox Code Playgroud)
这段代码从firebase获取用户的标记,我只想浏览标记数组.
这是控制台给我的东西:

如您所见,我无法访问该阵列.你知道我怎么能这样做吗?
提前致谢.
我知道还有另外一个类似的问题,但它适用于较旧版本的AFNetworking,并且无论如何都没有真正回答它.
我有以下代码:
AFHTTPRequestOperationManager* manager = [AFHTTPRequestOperationManager manager];
manager.securityPolicy.allowInvalidCertificates = YES;
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername: currentUser() password: currentPassword()];
__block NSDictionary* response = nil;
AFHTTPRequestOperation* operation = [manager
GET: @"https://10.20.30.40:8765/foobar"
parameters: [NSDictionary dictionary]
success:^(AFHTTPRequestOperation* operation, id responseObject){
response = responseObject;
NSLog(@"response (block): %@", response);
}
failure:^(AFHTTPRequestOperation* operation, NSError* error){
NSLog(@"Error: %@", error);}
];
[operation waitUntilFinished];
NSLog(@"response: %@", response);
...
Run Code Online (Sandbox Code Playgroud)
如果我运行它,我将在日志中看到的是:
2013-12-09 09:26:20.105 myValve[409:60b] response: (null)
2013-12-09 09:26:20.202 myValve[409:60b] response (block): {
F00005 = "";
F00008 = "";
F00013 …Run Code Online (Sandbox Code Playgroud) 有没有办法从主线程同步查询javascript?
使用具有回调参数的异步函数从本机代码查询Javascript以处理响应:
func evaluateJavaScript(_ javaScriptString: String, completionHandler completionHandler: ((AnyObject!, NSError!) -> Void)?)
Run Code Online (Sandbox Code Playgroud)
通过暂停线程并使用信号量控制执行,通常可以将异步行为转为同步:
// Executing in the main thread
let sema = dispatch_semaphore_create(0)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
// Background thread
self.evaluateJavaScript("navigator.userAgent", completionHandler: { (value:AnyObject!, error: NSError!) -> Void in
if let ua = value as? String {
userAgent = ua
} else {
ERROR("ERROR There was an error retrieving the default user agent, using hardcoded value \(error)")
}
dispatch_semaphore_signal(sema)
})
}
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)
Run Code Online (Sandbox Code Playgroud)
然而......在这种情况下,因为completionHandler是一直被称为主线程,代码死锁,因为completionHandler块永远不会执行(主线程暂停由dispatch_semaphore_wait …
我有一系列我正在执行的dispatch_async,我只想在完成后更新UI.问题是dispatch_async中的方法在一个单独的线程中调用某些内容,因此它在数据完全加载之前返回,并在加载所有内容之前调用dispatch_group_notify.
所以我引入一个无限循环让它等到标志设置.这是最好的方法吗?见下面的代码.
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_group_t group = dispatch_group_create();
for (...) {
dispatch_group_async(group, queue, ^{
__block BOOL dataLoaded = NO;
[thirdPartyCodeCallWithCompletion:^{
dataLoaded = YES;
}];
// prevent infinite loop
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)),
queue, ^{
dataLoaded = YES;
});
// infinite loop to wait until data is loaded
while (1) {
if (dataLoaded) break;
}
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
//update UI
});
}
Run Code Online (Sandbox Code Playgroud) 我是阻止的新手,我试图弄清楚如何在执行我的操作之前等待块完成(在这种情况下是一个nslog)所以我怎么能等到块完成之后再执行以下代码中的这个nslog: NSLog(@"convertedPhotos::%@",convertedImages);
convertedImages = [[NSMutableArray alloc] init];
for (NSDictionary *photo in photos) {
// photo is a dictionary containing a "caption" and a "urlRep"
[photoUrls addObject:photo[@"urlRep"]];
}
if (photoUrls.count) {
for (id photos in photoUrls){
NSString *urlString = photos;
[self base64ImageAtUrlString:urlString result:^(NSString *base64) {
[jsonWithPhotos setObject:convertedImages forKey:@"photo64"];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonWithPhotos
options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
error:&error];
if (! jsonData) {
NSLog(@"Got an error: %@", error);
} …Run Code Online (Sandbox Code Playgroud)