0

I am developing an app using SDK 8.1, Apple LLVM 6.0 and Xcode 6.1.1. The deployment target is 6.0. I'm using NSOperationQueue and I want to use QoS whenever it's available.

The code I'm using is:

if ([self.operationQueue respondsToSelector:@selector(setQualityOfService:)] 
     && (&NSOperationQualityOfServiceUserInitiated)) {
    [self.operationQueue performSelector:@selector(setQualityOfService:) withObject: NSOperationQualityOfServiceUserInitiated];
} else {
    //Other stuff not related to the scope of this question
}

The error I get is:

Use of undeclared identifier 'NSOperationQualityOfServiceUserInitiated'

I added the if (&NSOperationQualityOfServiceUserInitiated) part to check if this constant exists. This code worked with older versions of Xcode/Obj-C Compiler.

I am able to use selectors with performSelectorWithIdentifier but what about constants that do not have a defined value in the docs? The value of this constant is set by NSQualityOfServiceUserInitiated but there is no definition for this value that can be hardcoded.

How do I fix that?

fpg1503
  • 7,492
  • 6
  • 29
  • 49
  • There's no need to check for `&NSOperationQualityOfServiceUserInitiated` in addition to the `qualityOfService` method. Both were added together in iOS 8. – rmaddy Feb 27 '15 at 17:27
  • Why use `performSelector:withObject:` to call the `qualityOfService` method? Just call the method directly. – rmaddy Feb 27 '15 at 17:28
  • If I try to use it directly I get even more errors like `No visible @interface for NSOpertaionQueue declares the selector qualityOfService:` :/ It wasn't like that with GCC... – fpg1503 Feb 27 '15 at 17:28
  • Are you sure your Base SDK is set to iOS 8? – rmaddy Feb 27 '15 at 17:29
  • Is this a compile-time error, a run-time error, or an IDE error that you're seeing? – Ian MacDonald Feb 27 '15 at 17:29
  • IDE error that only shows up at compile-time, Base SDK is 8.1, when I set my Deployment Target to 8.0 everything works fine but the code only run on iOS 8 – fpg1503 Feb 27 '15 at 17:31

1 Answers1

0

There are several things wrong with the code.

  1. NSOperationQualityOfServiceUserInitiated is a native type (NSInteger) so you can't use it the way that you are in either line.
  2. The qualityOfService is a property of type NSQualityOfService. Your attempt to pass an argument to the qualityOfService method (getter method) makes no sense. If you are trying to set the quality of service, you need to call the setter but you can't use performSelector.

You want:

if ([self.operationQueue respondsToSelector:@selector(qualityOfService)]) {
    self.operationQueue.qualityOfService = NSOperationQualityOfServiceUserInitiated;
} else {
    //Other stuff not related to the scope of this question
}

This code will compile fine as long as your Base SDK is iOS 8.0 or later. The Deployment Target doesn't matter.

If you also want to build this code with Xcode 5 or earlier (a Base SDK of iOS 7 or earlier) then you need to wrap the code with the proper compiler directives to check for the Base SDK.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • Sorry, I meant to use the setter but you're right `NSOperationQualityOfServiceUserInitiated` is `NSInteger`. I used your code replacing `@selector(qualityOfService)` with `@selector(setQualityOfService)`. I had tried that before but it wasn't working, it's probably an issue with my Xcode installation since it stops/start working out of nowhere :/ – fpg1503 Feb 27 '15 at 18:25
  • You have to use `@selector(setQualityOfService:)`. Note the colon at the end of the selector name. That's important. – rmaddy Feb 27 '15 at 19:53