从早上开始我一直在尝试,但是我没有达到我想要的。
我尝试了DispatchQueue.main.async和完成块,但是UI中的“提交”按钮仍然冻结,等待从服务器返回数据。这是我的代码:
func createData(request:Crudpb_CreateRequest, with completion: @escaping (String) -> Void) throws {
DispatchQueue.main.async {
self.response = try! self.client.create(request) // <---- How to handle error for this server call when the server is not available or is down?
completion(self.response.result)
}
}
我刚刚注意到我从以下代码中调用了第一个方法,这是一个同步一元函数,这可能是问题背后的原因。但是再次,我不知道如何在休假状态中调用第二个函数:
/// Synchronous. Unary.
internal func create(_ request: Crudpb_CreateRequest, metadata customMetadata: Metadata) throws -> Crudpb_CreateResponse {
return try Crudpb_CrudServiceCreateCallBase(channel)
.run(request: request, metadata: customMetadata)
}
/// Asynchronous. Unary.
@discardableResult
internal func create(_ request: Crudpb_CreateRequest, metadata customMetadata: Metadata, completion: @escaping (Crudpb_CreateResponse?, CallResult) -> Void) throws -> Crudpb_CrudServiceCreateCall {
return try Crudpb_CrudServiceCreateCallBase(channel)
.start(request: request, metadata: customMetadata, completion: completion)
}
服务器端代码:
func (*server) Create(ctx context.Context, req *crudpb.CreateRequest) (*crudpb.CreateResponse, error) {
var result string
firstName := req.GetAccount().GetFirstName()
lastName := req.GetAccount().GetLastName()
// id := gocql.TimeUUID()
fmt.Println("Triggered CREATE function on Go Server " + firstName + " " + lastName + "! Yayy!")
result = fmt.Sprintf("id for %s %s : %s", firstName, lastName, strconv.Itoa(rand.Intn(100)))
return &crudpb.CreateResponse{
Result: result,
}, nil
在从服务器获取结果时,我需要此应用程序/提交按钮不冻结。
请帮助。
答案 0 :(得分:1)
您仍在主线程上执行工作。async
仅使createData()
方法在任务完成之前返回。.但是任务仍会在某些时候处理在主线程中,在此期间您的应用程序将变得无响应 ..尝试使用全局队列代替..以保持主线程干净。
收到回复后,不要忘记在主线程上执行所有UI工作。
答案 1 :(得分:1)
请改用异步函数,并在create
函数的完成内部调用完成块。
func createData(request:Crudpb_CreateRequest, with completion: @escaping (String) -> Void) throws {
try! self.client.create(request) { (response: Crudpb_CreateResponse?, result: CallResult) in
DispatchQueue.main.async {
// This is assuming your completion involves UI operations. Otherwise there is no need for this async call.
let stringOutput = String(data: result.resultData!, encoding: String.Encoding.utf8))
completion(stringOutput)
}
}
}
答案 2 :(得分:0)
从createData方法中删除DispatchQueue.main.async块
func createData(request:Crudpb_CreateRequest, with completion: @escaping (String) -> Void) throws {
self.response = try! self.client.create(request)
completion(self.response.result)
}
仅在从api响应更新UI的地方使用主队列
myobj.createData(request: request, with: { string in
print(string)//background thread
DispatchQueue.main.async {
self.label.text = sting//main thread
}
})
答案 3 :(得分:0)
UI冻结,因为您在主线程上做过多的工作。您应该找出什么功能阻塞了主线程。 工具time profiler是查看哪个功能花费过多时间的简便方法。