Invalid token at start of a preprocessor expression Xcode [duplicate] - objective-c

This question already has an answer here:
Macro in Objective-C calling isEqualToString: produces error about invalid token
(1 answer)
Closed 6 years ago.
#define A7VERSION() ({[[[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:#"."] objectAtIndex:0] intValue];})
#define IS_OS_7 A7VERSION()>=7
The above declaration seems to compile well.
But as soon as I add it a .m file I get the following exception "invalid token at start of a preprocessor expression". I am not able to understand where I could be wrong
#implementation AppViewController
#if IS_OS_7
….
#else
….
#endif
#end

The problem has nothing to do with iOS 7.
Your #define does not lead to something that can be resolved at compile time. An #ifdef only works if the conditional is something that can be determined at compile time. It cannot be used to change behavior at runtime based on the environment an app is running on.

Related

What does “typedef void (^Something)()” mean [duplicate]

This question already has answers here:
Caret in objective C
(3 answers)
Closed 4 years ago.
I was trying to compile stk. During the configuration I get the error
System/Library/Frameworks/CoreAudio.framework/Headers/AudioHardware.h:162:2:
error: expected identifier or '(' before '^' token
(^AudioObjectPropertyListenerBlock)(
When I see the code I see ^ inside the function pointer declaration at line 162 in here. I know we can have * but what does ^ mean?
Code snippet :
#if defined(__BLOCKS__)
typedef void
(^AudioObjectPropertyListenerBlock)( UInt32 inNumberAddresses,
const AudioObjectPropertyAddress inAddresses[]);
As other answerers here say, it could be in C++/CLI.
But also, if you are on a macOS (like you hinted in one comment), this is an Objective-C block.
Its syntax is very very weird.
The block is like a C++ closures and Java anonymous inner classes, it can capture variables.
__block int insider = 0;
void(^block)() = ^{
// print insider here using your favourite method, printf for example
};
This is a complete NSObject (base Objective-C class), but is callable, this is not a mere function pointer.
Refer to this Apple document: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithBlocks/WorkingwithBlocks.html
Now, we go to the important question, I want to run this on Linux, how ???
LLVM supports block syntax, but you should refer to this StackOverflow question for more: Clang block in Linux?
So, you should compile your code in the LLVM compiler, and use -fblocks and -lBlocksRuntime.
Don't forget to install those Linux packages:
llvm
clang
libblocksruntime-dev
If you are already on macOS, just use -fblocks.

Lint error objectiveC

I have a linting error on my objC but I don't know how to resolve it, if I'm using the reinterpret_cast syntax, the app does not build anymore... Someone has an idea please?
error: NSString+EXT.h:9: Using C-style cast. Use reinterpret_cast(...) instead [readability/casting]
NSString+EXT.h
#ifndef ATOM_BROWSER_UI_COCOA_NSSTRING_ANSI_H_
#define ATOM_BROWSER_UI_COCOA_NSSTRING_ANSI_H_
#import <Foundation/Foundation.h>
#interface NSString(ANSI)
- (BOOL)containsANSICodes;
- (NSMutableAttributedString*)attributedStringParsingANSICodes;
#end
#endif // ATOM_BROWSER_UI_COCOA_NSSTRING_ANSI_H_
After multiple research and test, I fix the issue by following this thread
A macro like
#define REINTERPRET(type, expr) (*(type *)&(expr))
help me to refactorize and resolve the issue

NS_DESIGNATED_INITIALIZER expected : (colon)

I am trying to declare a designated initializer like this:
- (instancetype)initWithDelegate:(id <MyDelegate>)delegate NS_DESIGNATED_INITIALIZER;
But it is showing me this compilation error:
Expected ':'
Interestingly when I try to write it like this (reference link: Adopting Modern Objective-C) -
- (instancetype)init NS_DESIGNATED_INITIALIZER;
It shows this error:
Expected ';' after method prototype.
Any ideas on how to properly use NS_DESIGNATED_INITIALIZER?
NS_DESIGNATED_INITIALIZER macro is not defined in the library headers for Xcode 5 - you need Xcode 6 to use it. Note your link says "Pre-release".
The macro is defined in the following way (quoting NSObjCRuntime.h)
#ifndef NS_DESIGNATED_INITIALIZER
#if __has_attribute(objc_designated_initializer)
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
#else
#define NS_DESIGNATED_INITIALIZER
#endif
#endif
Note you can still use
- (instancetype)initWithDelegate:(id <MyDelegate>)delegate __attribute__((objc_designated_initializer));
in Xcode 5 or you can add that macro explicitly to your precompiled header.
Bear in mind you can only add this to interface or class extension declarations otherwise you'll get this error:
'objc_designated_initializer' attribute only applies to init methods of interface or class extension declarations

Linker error for global variable [duplicate]

This question already has answers here:
Accesing global variable giving linker error in objective C
(2 answers)
Closed 9 years ago.
I'm making a small, simple application, so I decided to use global variables over Singletons. I'm also only using one.
My app pulls an int from a small preference file, and that is set to the global variable as an NSInteger. The global variable may be changed while the app is running.
AppController.h
#import <Cocoa/Cocoa.h>
extern NSInteger preferenceNumber;
#interface ....
App Controller.m
-(void)someMethod {
...
//fileContents is a string containing the int that is inside the file
preferenceNumber = [fileContents intValue]
...
}
The Linker Errors (2):
Undefined symbols for architecture x86_64:
"_preferenceNumber", referenced from:
-[AppController someMethod1] in AppController.o
-[AppController someMethod2:] in AppController.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The bolded parts are the two errors.
What is causing this? What is the simplest, best way to solve it?
Just add one line in your implementation class:-
AppContollr.m
#implementation AppContoller
NSInteger preferenceNumber;

How do I disable NSLog?

I'd like to do the following in Xcode:
Find all NSLog commands without comments, and replace it with //NSLog...
In other words, I want to comment all NSLog calls. Is this possible? Is there an easy way to do this?
wait there is far more simple method. Just add the following lines when you dont need NSLOG to your constants file
#define NSLog //
and comment it when you need it.
EDIT: In latest Xcode, you get error on above statement. So I figured out the best way is
#define NSLog(...)
Update:
The answer bellow is actually much better. See here.
Initial answer:
There is a little hack that you could do. Search for all NSLog and replace them with //NSLog and than do another search for ////NSLog and replace them with //NSLog.
#define NSLog if(1) NSLog
if you dont want log set 1 as 0.
I have to do a separate answer because I cant comment yet, but one thing you really need to be careful about when you do a find and replace is something like this:
if(BOOL)
NSLog(#"blah blah");
[self doSomething];
If you comment out the nslog, the conditional gets associated with the method below it, correct me if I'm wrong
The answers you have are correct for your question. But. Your real question is how to turn of NSLogs in certain conditions. i.e. you want them to show for Debug builds, and not for Release builds. In which case try defining and using the DLog() macro as described on Cocoa Is My Girlfriend. If you're using Xcode4 it's even easier because the Debug and Release builds define and undefine DEBUG so you don't have to do that.
It's a lot easier than commenting and uncommenting lines of code.
#ifdef RELEASE
#define NSLog(...) do { } while (0)
#endif
is the best way i found so far.
#define NSLog(...)
add this line into your .pch file
if you want log than comment it
You can do this in a single find and replace operation. You can just do this simple Regular Expression replace. This handles both the commented(//) and non-commented lines. This also works even if the previous commented lines has more than two forward slashes(like ///)instead of rwo. You can refer this link. Do the following steps.
Select Edit > Find > Find and Replace in Workspace
Style => Regular Expression
Type (/)*(NSLog.*) in Find field.
Do the find operation.
Type //\2 in the Replace field.
Do the replace operation.
Enjoy the beauty of regular expressions ;-)
I would do this
#define EnableNSLog 1
#if EnableNSLog == 0
#define NSLog //
#elif EnableNSLog == 1
#warning Disable NSLog
#endif
This should generate a warning message to remind me to disable NSLog before final release.
right click on NSLog statement in xcode and select "find in project" as text.you would be prompted to a new window where you can follow the guidance given by Mihai Fratu.
TNQ
in the Menu bar : Edit > Find > Find and Replace in Workspace
then, display options to use regular expressions.
search/replace for "[^/]NSLog"
How to disable NSLog in Xcode for Production stage
Add #define NSLog in appName-Prefix.pch file in Supporting Files Folder of your project
and result file code look like...
// Prefix header for all source files of the 'NSLog' target in the 'NSLog' project
//
#import <Availability.h>
#ifndef __IPHONE_4_0
#warning "This project uses features only available in iOS SDK 4.0 and later."
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif
//Add this to disable NSLog
#define NSLog //
You can use following Preprocessor Directives, it will not go with release mode.
So you don't have to commenting NSLog().
#ifdef DEBUG
NSLog(#"YOUR MESSAGE HERE!");
#endif
try this also:
#define NSLog(#"YOUR MESSAGE HERE!") do { } while (0)
Add the following line to your .pch file
#define NSLog
for enable comment it