0

I'm working on a project that uses OpenCV, which has forced me to branch out a little bit into C++ and Objective-C. I built a small Objective-C class that calls Objective C++ functions from the OpenCV framework, and bridged that into Swift.

Inside the objective-c class, I've got a handful of NSInteger members that I want to be able to change from UI. But when I try to get or set them, it crashes with the familiar unexpectedly found nil while unwrapping an Optional value.

I have no doubt that it's an elementary mistake, but I've been spinning my wheels for awhile and am having trouble narrowing it down. If somebody could take a look at my class and tell me what's wrong that would be great.

.h file @interface OpenCVWrapper : NSObject

// This is a singleton for providing global access to the OpenCV Wrapper
+ (OpenCVWrapper *)sharedInstance;

- (UIImage *)processImageWithOpenCV:(UIImage*)inputImage;
- (void)setupVideoCamera:(UIView*) parentView;

// Filtering properties
@property (atomic, assign) NSInteger hMin;
@property (nonatomic, assign) NSInteger hMax;
@property (nonatomic, assign) NSInteger sMin;
@property (nonatomic, assign) NSInteger sMax;
@property (nonatomic, assign) NSInteger vMin;
@property (nonatomic, assign) NSInteger vMax;


#ifdef __cplusplus
@property (nonatomic, retain) CvVideoCamera* videoCamera;
@property (nonatomic, retain) VideoHandler* videoHandler;
#endif

@end

.mm file

@implementation OpenCVWrapper : NSObject

@synthesize videoHandler;
@synthesize videoCamera;

@synthesize hMin;
@synthesize hMax;
@synthesize sMin;
@synthesize sMax;
@synthesize vMin;
@synthesize vMax;

// This is how a singlegton is created in Objective-C (or so I'm told)
static OpenCVWrapper *sharedInstance = nil;
+ (OpenCVWrapper *)sharedInstance {
    if (sharedInstance == nil) {
        sharedInstance = [[super allocWithZone:NULL] init];
    }
    return sharedInstance;
}

// Initialize the variables
// hue is from 0 to 180, saturation and value go from 0 to 255
-(id) init {
    self = [super init];
    self.hMin = 0;
    self.sMin = 0;
    self.vMin = 0;
    self.hMax = 180;
    self.sMax = 255;
    self.vMax = 255;
    return self;
}

I then have bridging header that imports the .h file, and the compiler recognizes OpenCVWrapper.sharedInstance, but if I try to get or set sharedInstance.hMin it finds an unexpected nil and crashes.

Any pointers would be greatly appreciated!

Erik
  • 2,299
  • 4
  • 18
  • 23
  • what are **CvVideoCamera** and **VideoHandler** are? are they Objective-C objects ? – Karim H Jun 18 '16 at 14:14
  • Looking at your code snippets, `OpenCVWrapper.sharedInstance.hMin` should not even compile. Is there also a `sharedInstance` property? Anyway, try `OpenCVWrapper.sharedInstance().hMin`. Note the parentheses. – Anatoli P Jun 18 '16 at 15:05
  • Also, it looks like there is a better way to set up a singleton, see this:http://stackoverflow.com/questions/7568935/how-do-i-implement-an-objective-c-singleton-that-is-compatible-with-arc – Anatoli P Jun 18 '16 at 15:24
  • @Omniprog Thanks for the info. I'll update the way I have the singleton setup to match that. – Erik Jun 19 '16 at 02:58
  • @Karim CvVideoCamera is a C++ class that's part of OpenCV. VideoHandler is an Objective-C object that is just set as the delegate for CvVideoCamera and contains a few methods for that get called before frames render. – Erik Jun 19 '16 at 02:58

1 Answers1

0

The problem turned out to be unrelated to these classes. There was a dangling storyboard reference that was causing the crash.

@IBOutlet weak var slider1:UISlider!
@IBOutlet weak var slider2:UISlider!

@IBAction func sliderChanged(sender:UISlider) {
    switch sender {
        case slider1: OpenCVWrapper.sharedInstance().hMin = NSInteger(sender.value)
        case slider2: OpenCVWrapper.sharedInstance().hMax = NSInteger(sender.value)
    }
}

The sliderChanged function was getting called, so I overlooked the fact that I forgot to hook up the outlets and assumed the nil had something to do with accessing the sharedInstance.

Thanks to everyone who took time to look over my code and offer suggestions.

Erik
  • 2,299
  • 4
  • 18
  • 23