Ios 获得;从主线程访问引擎后,从后台线程修改自动布局引擎;即使在使用DispatchQueue时
你好,我正在尝试创建一个简单的应用程序,从我的web服务器获取注释,然后用它们传播地图。唯一的问题是,当我在30秒后调用函数bob从另一个位置获取新注释时,它给出了上面的错误,我尝试使用DispatchQueue.main.async修复它,但没有成功。感谢您的帮助 下面是讨论中的函数Ios 获得;从主线程访问引擎后,从后台线程修改自动布局引擎;即使在使用DispatchQueue时,ios,swift,xcode,Ios,Swift,Xcode,你好,我正在尝试创建一个简单的应用程序,从我的web服务器获取注释,然后用它们传播地图。唯一的问题是,当我在30秒后调用函数bob从另一个位置获取新注释时,它给出了上面的错误,我尝试使用DispatchQueue.main.async修复它,但没有成功。感谢您的帮助 下面是讨论中的函数 // this is the test to see if it can add a new annotation after 30 seconds if bob == 30{ let user_lat
// this is the test to see if it can add a new annotation after 30 seconds
if bob == 30{
let user_lat_temp = 26.7709
let user_lng_temp = -80.1067
DispatchQueue.main.async() {
// Do stuff to UI
self.GetAnnotations(lat: user_lat_temp, lng: user_lng_temp)
}
// reset it to see if it breaks
bob = 0
}
bob = bob + 1
print("bob: ", bob)
}
这是完整的代码
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
@IBOutlet weak var mapView: MKMapView!
let access_token = ""
let manager = CLLocationManager()
var firstTime = 1
var user_lat = 0.0
var user_lng = 0.0
var bob = 0
override func viewDidLoad() {
super.viewDidLoad()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation = locations[0]
user_lat = userLocation.coordinate.latitude
user_lng = userLocation.coordinate.longitude
self.mapView.showsUserLocation = true
if firstTime == 1{
GetAnnotations(lat: user_lat, lng: user_lng)
firstTime = 0
}
// this is the test to see if it can add a new annotation after 30 seconds
if bob == 30{
let user_lat_temp = 26.7709
let user_lng_temp = -80.1067
DispatchQueue.main.async() {
// Do stuff to UI
self.GetAnnotations(lat: user_lat_temp, lng: user_lng_temp)
}
// reset it to see if it breaks
bob = 0
}
bob = bob + 1
print("bob: ", bob)
}
func GetAnnotations(lat: Double, lng: Double){
guard let url = URL(string: "http://192.168.1.10:7888/api/?controller=location&action=get_locations") else {return}
var request = URLRequest(url: url)
request.httpMethod = "POST"
let postString = "access_token=\(access_token)&lat=\(lat)&lng=\(lng)";
request.httpBody = postString.data(using: String.Encoding.utf8)
URLSession.shared.dataTask(with: request) { (data, response, err) in
if let error = err {
print("the server is not responding \(error)")
}
if let response = response {
// if the user has a bad access token or is logged out
if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 401{
print("bad access token")
return
}
}else{
print("the server is not responding")
}
print(response)
guard let data = data else { return }
// parse the json for the locations
do {
let mapJSON = try JSONDecoder().decode(parseJsonLocations.self, from: data)
let user_id = mapJSON.user_info.user_id
print(user_id)
print(mapJSON.locations.count)
// do map
let distanceSpan:CLLocationDegrees = 10000
let userLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(lat, lng)
self.mapView.setRegion(MKCoordinateRegionMakeWithDistance(userLocation, distanceSpan, distanceSpan), animated: true)
self.mapView.delegate = self
var i = 0
while i < mapJSON.locations.count {
let location_id = mapJSON.locations[i].location_id
let location_name = mapJSON.locations[i].location_name
let location_lat = mapJSON.locations[i].lat
let location_lng = mapJSON.locations[i].lng
let locationsLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location_lat, location_lng)
let subtitle = "location_id: \(location_id)"
let userAnnotation = Annotation(title: location_name, subtitle: subtitle, coordinate: locationsLocation)
self.mapView.addAnnotation( userAnnotation )
i = i + 1
}
} catch {
print("error trying to convert data to JSON")
print(error)
}
}
}.resume()
}
}
导入UIKit
导入地图套件
导入核心定位
类ViewController:UIViewController、MKMapViewDelegate、CLLocationManagerDelegate{
@ibvar映射视图:MKMapView!
让我们访问\u令牌=“”
let manager=CLLocationManager()
var firstTime=1
var user_lat=0.0
var用户液化天然气=0.0
var bob=0
重写func viewDidLoad(){
super.viewDidLoad()
manager.delegate=self
manager.desiredAccuracy=KCallocationAccuracyBest
manager.requestWhenUseAuthorization()
经理:startUpdatingLocation()
}
重写函数didReceiveMemoryWarning(){
超级。我收到了记忆警告()
//处置所有可以重新创建的资源。
}
func locationManager(manager:CLLocationManager,didUpdateLocations位置:[CLLocation]){
让userLocation=locations[0]
user_lat=userLocation.coordinate.latitude
user_lng=userLocation.coordinate.longitude
self.mapView.showsUserLocation=true
如果firstTime==1{
获取注释(lat:user\u lat,lng:user\u lng)
第一次=0
}
//这是一个测试,看看它是否可以在30秒后添加新注释
如果bob==30{
让用户_lat_temp=26.7709
让用户_lng_temp=-80.1067
DispatchQueue.main.async(){
//对UI做一些事情
self.GetAnnotations(lat:user\u lat\u temp,lng:user\u lng\u temp)
}
//重置它以查看它是否损坏
鲍勃=0
}
鲍勃=鲍勃+1
打印(“鲍勃:,鲍勃”)
}
func GetAnnotations(纬度:双精度,液化天然气:双精度){
guard let url=url(字符串:http://192.168.1.10:7888/api/?controller=location&action=get_locations)否则{return}
var-request=URLRequest(url:url)
request.httpMethod=“POST”
让postString=“访问令牌=\(访问令牌)&lat=\(lat)&lng=\(lng)”;
request.httpBody=postString.data(使用:String.Encoding.utf8)
URLSession.shared.dataTask(with:request){(data,response,err)在
如果let error=err{
打印(“服务器没有响应\(错误)”)
}
如果让响应=响应{
//如果用户具有错误的访问令牌或已注销
如果让httpResponse=响应为?HTTPURLResponse{
如果httpResponse.statusCode==401{
打印(“错误访问令牌”)
返回
}
}否则{
打印(“服务器没有响应”)
}
打印(答复)
guard let data=data else{return}
//解析位置的json
做{
让mapJSON=try JSONDecoder().decode(parseJsonLocations.self,from:data)
让user\u id=mapJSON.user\u info.user\u id
打印(用户id)
打印(mapJSON.locations.count)
//做地图
let distanceSpan:CLLocationDegrees=10000
let userLocation:CLLocationCoordinate2D=CLLocationCoordinate2DMake(lat,lng)
self.mapView.setRegion(MKCoordinateRegionMakeWithDistance(用户位置、距离跨度、距离跨度),动画:true)
self.mapView.delegate=self
变量i=0
而i
在很多其他地方,你都没有注意到你可能在哪条线上的问题
你是说
if firstTime == 1 {
GetAnnotations( // ...
self.mapView.setRegion
// ... and all that follows ...
不确定你是否在主线上
然后,在GetAnnotations中,您会说
if firstTime == 1 {
GetAnnotations( // ...
self.mapView.setRegion
// ... and all that follows ...
不确定你是否在主线上
我并不是说你在那些时刻不在主线上,但也没有理由认为你在主线上。你应该检查一下并把它整理好。还有很多地方你没有注意到你可能在哪条线上的问题 你是说
if firstTime == 1 {
GetAnnotations( // ...
self.mapView.setRegion
// ... and all that follows ...
不确定你是否在主线上
然后,在GetAnnotations中,您会说
if firstTime == 1 {
GetAnnotations( // ...
self.mapView.setRegion
// ... and all that follows ...
不确定你是否在主线上
我并不是说你在那些时刻不在主线上,但也没有理由认为你在主线上。你应该检查一下并把它整理好。你的想法是对的;显式地在主队列上调度UI更新,很遗憾,您调度了错误的函数
GetAnnotations
(按照惯例