How to make debug code using #ifdef directive. Objective-c - objective-c

i want to make a question about developing using #ifdef directive.
I want do make some code in objective-c only for debug use, for example:
in main function do this:
#define DEBUG_LEVEL
in my interface do this:
#ifdef DEBUG_LEVEL
BOOL editorIsDragged;
BOOL editorIsSelected;
#endif
.... other property
#ifdef #DEBUG_LEVEL
#property (nonatomic, readwrite) BOOL editorIsDragged;
#property (nonatomic, readwrite) BOOL editorIsSelected;
#endif
then in my implementation do this:
#ifdef #DEBUG_LEVEL
#synthetize editorIsDragged, editorIsSelected;
#endif
but i receve an error because in synthetize editorIsDragged and editorIsSelected are not defined.
If i try to define my own setter/getter method I receive the same error, because my vars (editorIsDragged and editorIsSelected) does not exist for XCode!
I in C use this method for write only debug code, but in obj-c what i must use??
thank you!

Shouldn't you put your #define DEBUG_LEVEL in a header file that gets included in all places that needs to know it? Like setting in in the build settings or putting in the *.pch. And I'm not sure if that a typo but you have also #define #DEBUG_LEVEL (see the second hash?) in the code here.

Related

Hide an Objective-C initializer (or method) from Swift

I have a Framework with has one Objective-C class with one designated initializer which takes two NSArrays. Inside the Framework, I have defined a Swift extension which provides an extra initializer which takes an array of tuples instead of the two arrays.
When importing the Framework eternally, is it possible to hide the original Objective-C initializer from Swift (so only the initializer taking the array of tuples can be used) but keep it available when using the Framework from Objective-C code?
Answer by #mattt:
Use the NS_SWIFT_UNAVAILABLE macro (available only on Xcode 7 and up).
You could:
YourApp-Brindging-Header.h
#define __BRIDGING__
#import "YourObjCObject.h"
#undef __BRIDGING__
YourObjCObject.h
#import <Foundation/Foundation.h>
#interface YourObjCObject : NSObject
#property (assign, nonatomic) NSInteger count;
- (instancetype)initWithArray:(NSArray *)ary1 Array2:(NSArray *)ary2 NS_DESIGNATED_INITIALIZER
#ifdef __BRIDGING__
NS_UNAVAILABLE
#endif
;
#end

Mark property as deprecated in Objective C

How can I mark a #property in Objective C as deprecated?
Unless you really want to deprecate based on iOS version, which I suspect you don't want to do, you can use DEPRECATED_ATTRIBUTE
#property (strong) NSObject *object DEPRECATED_ATTRIBUTE;
from NSObjCRuntime.h
#define NS_AVAILABLE(_mac, _ios)
#define NS_AVAILABLE_MAC(_mac)
#define NS_AVAILABLE_IOS(_ios)
#define NS_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep)
#define NS_DEPRECATED_MAC(_macIntro, _macDep)
#define NS_DEPRECATED_IOS(_iosIntro, _iosDep)
you can use these macros
this is one example in UITableViewCell.h
#property(nonatomic,copy) NSString *text NS_DEPRECATED_IOS(2_0, 3_0); // default is nil
You can also use DEPRECATED_MSG_ATTRIBUTE("Use anotherProperty instead.") and provide a meaningful message hinting the user what to use in place of the deprecated property.
Xcode will show a warning when the property is used.
example:
#property (nonatomic) NSString *someProperty DEPRECATED_MSG_ATTRIBUTE("Use anotherProperty instead.");
you can type macro like this below one in .pch to be gloabl for all the app
#define DEPRECATED_ATTRIBUTE __attribute__((deprecated))
in mark the method as following example
-(void) exmapleMethodName DEPRECATED_ATTRIBUTE{
// code
}

Why can you only #define an NSString constant in a header file?

A curious objective-c newbie question. I noticed that I can #define an NSString in the .h file, but not in the .m file... why?
The declaration in question is:
#define kSomeString #"This is a string"
That declaration fails with an error if its in the .m file.
you CAN define them also in the implementation files.
#import "SAiPadHomeViewController.h"
#define hugo #"Test"
#interface SAiPadHomeViewController ()
#end
#implementation SAiPadHomeViewController
#end
This example works - try it.
Greetz!

Using Methods Without Declaring them in the header

Recently I used an opaque pointer type in my code. I did this because I wanted to use c++ code in my obj c project without having to change every single file to .mm.
The way I use the c++ code is that I have a opaque pointer to my c++ code as a member of a .mm file. All the c++ is hidden in the implementation file.
In this class that contains my c++ I have a need to import an existing class "MyClass". I can import it fine in the implementation class but if I try to import it in the header I get c++ errors saying " ISO C++ forbids declaration of 'CARingBufferCPPWrapper' with no type".
I "can" just write the method in the .mm file and omit it from the header but I get a warning say that my .mm file may not respond to the method.
A lot of this is quite new to be so my terminology may be a little off. Let me know if I can clarify my question in any way.
TLDR: How can Class X Safely call a method in Class Y without the method being declared in Class Y header?
//My Header
#import <Foundation/Foundation.h>
#import <AudioToolbox/AudioToolbox.h>
#define kBufferLength 5120
//#define "Myclass.h"
typedef struct ringbufferobj * RingBufferOBJ;
RingBufferOBJ newRingBufferOBJ();
#interface CARingBufferCPPWrapper : NSObject {
RingBufferOBJ ringbuffer;
NSThread *producerthread;
int duration;
}
#property (nonatomic, retain) NSThread *producerthread;
#property(nonatomic)int duration;
//-(void)myclassfunction(MyClass *)classref
#end
//My Implementation .mm
#import "CARingBufferCPPWrapper.h"
#import "CARingBuffer.h"
#import <AudioToolbox/AudioToolbox.h>
#import "MyClass.h"
struct ringbufferobj
{
CARingBuffer *ringbuffer;
AudioBufferList *inputbuffer;
Float64 firstInputSampleTime;
Float64 firstOutputSampleTime;
Float64 inToOutSampleTimeOffset;
BOOL producerthreadisrunning;
};
RingBufferOBJ newRingBufferOBJ(){
RingBufferOBJ ringbuffer=(RingBufferOBJ)malloc(sizeof(struct ringbufferobj));
return ringbuffer;
}
#implementation CARingBufferCPPWrapper
#synthesize producerthread;
#synthesize duration;
-(void)myclassfunction(MyClass *)classref
{
}
#end
I'm not quite sure what your question is as I couldn't find anything that actually asks anything. (I even Cmd+F'd for "?"). I'm assuming however, that you're asking what you can do to get rid of that warning?
-If a method is declared above the method it is called it, there should be no warning. ( methods are compiled in order). To get rid of such a warning, you'd have to forward declare the method signature. (This is conventionally in the header, but I don't think there's anything stopping you just doing it at the top of your .m)
-(void) methodA {
..do something
[self methodB]; //Warning here because the compiler has not yet seen methodB
}
-(void) method B {
..[self methodA]; //No warning, compiler knows what methodA is at this point.
}

Using static .lib (c) in iOS Project - Expected '=',',',';','asm' or 'attribute' before

I am trying to use static libraries that are written in c in an iOS Project. I included the .lib files and the .h into the iOS project. When I try to import the header files in one of my objective-C classes I get a lot of Expected '=',',',';','asm' or 'attribute' before... errors in the .h file of my static library.
I am using xCode4 for Development which seems to have added the libs correctly. When I open the project with Xcode 3 the libs are added to the Target Group "link binary with libraries" as stated in How to resolve linking error - static lib iPhone.
I got the static libs from a company that actually uses these libraries so I guess the header file is not at fault. I could not find any errors myself.
Is there a way to use .lib files with correct header files in an ios project? Or do I have to do anything besides adding the lib files to the target group in order to use them in my project?
Best Regards,
Mike
edit
the actual error message:
Expected * before *
Expected '=',',',';','asm' or 'attribute' before _far _pascal
The actual code where the header is imported:
#import <Foundation/Foundation.h>
#import "SomethingDll.h"
#interface AccountingEntry : NSObject {
NSString *entryDescription;
NSDate *entryDate;
double entryAmount;
NSString *entryType;
}
#property (nonatomic, retain) NSString *entryDescription;
#property (nonatomic, retain) NSDate *entryDate;
#property (nonatomic) double entryAmount;
#property (nonatomic, retain) NSString *entryType;
//class methods go here
//instance methods go here
-(id)initWithDescription:(NSString *)eDesc date:(NSDate*)eDate amount:(double)eAmount type:(NSString *)eType;
#end
The .h file of the lib.
#ifndef __SOMETHING_DLL
#define __SOMETHING_DLL
// constants for a function
#define FIRST_ERRTEXT 0
#define NEXT_ERRTEXT 1
/*
...
some other #define of constants
*/
// Callback-Pointer Definitionen
#define INFO_FUNC_DECL BOOL (CALLBACK *lpInfoFunc)(int)
#define FILETRANS_FUNC_DECL void (CALLBACK *lpFileTransFunc)(int,long)
// Funktionsdeklarationen
#ifdef WIN32
#define IMPORTAPI WINAPI
#else
#define IMPORTAPI _far _pascal
#endif
#ifdef __cplusplus
extern "C" {
#endif
void IMPORTAPI Something_Config( int iLogLevel, char *szLogFile,
long lTimeOut_Connect, long lTimeOut,
long lTimeout_GetFile, long lTime_Info,
int iSSLVersion, char *szSSLCipher,
char *szVerifyCertificateFile, char *szVerifyCertificatePath);
/*
...
a lot of other functions
...
*/
#ifdef __cplusplus
}
#endif
#endif // End
It seams that this lib is for Win32, the _far _pascal directive is not available on gcc and the other errors may come from missing definitions.
Maybe you have to look for another lib to do the job.