原始功能看起来像这样:
CImpl
但是由于同步功能在Swift中的工作方式,每月费用值不会更新。所以然后我尝试更改我的代码,以便将尽可能多的代码放入异步函数本身,它看起来像这样:
//! 2018.05.13 13:31:34 CST
//! Find the max-area bounding-rect of approxed-poly-contours
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int findMaxRect(){
/// Read, cvtColor, threshold
Mat img, gray, threshed;
img = imread("car.jpg");
cvtColor(img, gray, COLOR_BGR2GRAY);
threshold(gray, threshed, 100, 255, THRESH_OTSU|THRESH_BINARY);
/// Find contours
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(threshed, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
/// Find the max boundingRect of approxed-contours
double max_area = -1;
Rect max_rect;
int idx = -1;
vector<Point2f> contour_poly;
for (int i = 0; i < contours.size(); i++){
/// Approx the contour
Mat contour = Mat(contours[i]);
double arclen = arcLength(contour, true);
approxPolyDP(contour, contour_poly, 0.03*arclen, true);
/// Get the bounding box
Rect rect = boundingRect(Mat(contour_poly));
/// Update the max_area_box
double area = rect.width*rect.height;
if(area>max_area){
max_area = area;
max_rect = rect;
}
}
cout << max_rect<<endl;
/// Draw the max rect
Mat drawing = img.clone();
rectangle(drawing, max_rect.tl(), max_rect.br(), Scalar(0,255,0), 1,8,0);
/// Crop
Mat dst = img(max_rect);
/// Display
imshow("drawing", drawing);
imshow("dst", dst);
waitKey(0);
return 0;
}
int main(int argc, char** argv){
//test_contours();
findMaxRect() ;
}
但问题是现在“sum”的值为0,因为我在此异步函数之外使用了一个变量。我已经看到在多个问题上提出了这个问题,但我无法在任何地方找到答案。这个问题的解决方案是什么
答案 0 :(得分:1)
在获取数据时使用完成处理程序作为触发器更新UI。
具有完成处理程序的设置功能:
func retrieveMonthlySpent(month:String, year:String, completion: ((Double) -> Void)? = nil) {
FirebaseFunctions().retrieve(from: .expense, username: self.username as! String, returning: Expenses.self) { (expenses) in
self.monthlyExpenses = expenses
var sum = 0.0
for expense in self.monthlyExpenses {
if expense.modificationDate.convertToMonth() == month && expense.expense && expense.modificationDate.convertToYear() == year {
sum += expense.convertedAmount
}
}
completion(sum)
}
}
在viewController中使用它,例如:
func retrieveMonthlySpent(month:"05", year:"1996") { result in
self.sumLabel.text = result
}
很容易就像Thanos抓住他的手指一样:)
答案 1 :(得分:0)
如果要调用异步API,则必须使用完成处理程序:
func retrieveMonthlySpent(month:String, year:String, success: @escaping (Double) -> Void) {
FirebaseFunctions().retrieve(from: .expense, username: self.username as! String, returning: Expenses.self) { (expenses) in
self.monthlyExpenses = expenses
var sum:Double = 0
for expense in self.monthlyExpenses{
if expense.modificationDate.convertToMonth() == month && expense.expense && expense.modificationDate.convertToYear() == year{
sum += expense.convertedAmount
}
}
success(sum)
}
}
您可以使用当前控制器中的此方法:
self.retrieveMonthlySpent(month: "", year: "") { (sum) in
print(sum)
}
或者从其他ViewController,您可以这样使用:
Xviewcontroller().retrieveMonthlySpent(month: "", year: "") { (sum) in
total = sum
}
为了更好的代码重用性,您需要将此方法放在superviewcontroller或任何公共类中。