2

I study how to use C++ with Swift in one project.

I have C++ class with interface

class SwypeDetect { public: SwypeDetect(); void asyncFunction(int &a); }; 

and implementation

SwypeDetect::SwypeDetect() {} void SwypeDetect::asyncFunction(int &a) { a = 1; sleep(3); a = 10; sleep(3); a = 100; } 

asyncFunction just change value of argument a three time each three seconds. Of course I create Objective-C wrapper

@interface Wrapper() @property (nonatomic, assign) SwypeDetect detector; @end @implementation Wrapper - (instancetype) init { self = [super init]; if (self) { _detector = SwypeDetect(); } return self; } - (void)asyncFunction:(int *)a { _detector.asyncFunction(*a); } @end 

And then use this wrapper in Swift class

class ViewController: UIViewController { let queue = DispatchQueue(label: "wrapper queue", attributes:.concurrent) var valueA: Int32 = 0 { didSet { print("new valueA \(valueA) on time \(Date())") } } var detector: Wrapper? { didSet { if let detector = detector { queue.async { detector.asyncFunction(&self.valueA) } } } } override func viewDidLoad() { super.viewDidLoad() detector = Wrapper() } } 

I expect that didSet block of valueA would be call three times, but in console I see only call with last change of valueA: "new valueA 100 on time 2018-03-26 11:50:18 +0000". What could I do to change this behaviour?

2
  • Swift registers the changed value only on return from detector.asyncFunction(&self.valueA). Commented Mar 26, 2018 at 12:32
  • I see that, but how can I observe changes while before return from detector.asyncFunction(&self.valueA)? Commented Mar 26, 2018 at 12:34

1 Answer 1

2

You have to say somewhere 'the variable is changed'. You can do it using closures/blocks/lambdas for instance

ViewController.swift

import UIKit class ViewController: UIViewController { let queue = DispatchQueue(label: "wrapper queue", attributes:.concurrent) var valueA: Int32 = 0 { didSet { print("new valueA \(valueA) on time \(Date())") } } var detector: Wrapper? { didSet { if let detector = detector { queue.async { detector.asyncFunction(&self.valueA) { value in print("iteration value: \(value)") } } } } } override func viewDidLoad() { super.viewDidLoad() detector = Wrapper() } } 

Wrapper.h

#import <Foundation/Foundation.h> @interface Wrapper : NSObject - (instancetype) init; - (void)asyncFunction:(int *)a progressHandler: (void(^)(int))progressHandler; @end 

Wrapper.mm

#import "Wrapper.h" #import "SwypeDetect.hpp" @interface Wrapper() @property (nonatomic, assign) SwypeDetect detector; @end @implementation Wrapper - (instancetype) init { self = [super init]; if (self) { _detector = SwypeDetect(); } return self; } - (void)asyncFunction:(int *)a progressHandler: (void(^)(int))progressHandler { _detector.asyncFunction(*a , progressHandler); } @end 

SwipeDetect.cpp

#include "SwypeDetect.hpp" #include <unistd.h> #include <iostream> SwypeDetect::SwypeDetect() {} void SwypeDetect::asyncFunction(int &a, std::function<void(int)> f) { std::cout << "Come up and C++ me some time." << std::endl; a = 1; f(a); sleep(1); a = 10; f(a); sleep(1); a = 100; f(a); } 

SwypeDetect.hpp

#include <stdio.h> #include <functional> class SwypeDetect { public: SwypeDetect(); void asyncFunction(int &a, std::function<void(int)> f); }; 

testsetsetset-Bridging-Header.h

#import "Wrapper.h" 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.