How to call the define variable in another file - ios

I have a define variable is a string like this
#define kyouTubeLink #"<iframe width='%d' height='%d' src='http://www.youtube.com/embed/%#?showinfo=0&modestbranding=1&rel=0&showsearch=0' frameborder='0' scrolling='0' allowfullscreen></iframe>";
so how to call this variable in another file.Thanks in advance

You cannot reference a variable that is #define-d in another translation unit. You can put the definition in a header file, and #include it from any translation unit that needs the definitions.
Since the definition is a C string literal, though, you would be better off defining a constant extern variable for it, putting the declaration in a header, defining it in one of your translation units, and using everywhere else:
Common header (say, "YouTubeShared.h"):
extern const NSString* kyouTubeLink;
First translation unit (e.g. "AppDelegate.m" or whatever is a file that is better suited to hold the constant)
#include "YouTubeShared.h"
const NSString *kyouTubeLink = #"<iframe width='%d' height='%d' src='http://www.youtube.com/embed/%#?showinfo=0&modestbranding=1&rel=0&showsearch=0' frameborder='0' scrolling='0' allowfullscreen></iframe>";
... // More things go here
Second translation unit:
#include "YouTubeShared.h"
... // More things go here
NSString *res = [NSString stringWithFormat:kyouTubeLink, 123, 456];

Related

What does OBJC_EXPORT keyword in Objective-C mean?

When I am using this method class_getName(), i find it is declared like this:
**OBJC_EXPORT** const char *class_getName(Class cls)
What does OBJC_EXPORT mean?
If you CMD+CLICK on the symbol, you'll see it's not a keyword. OBJC_EXPORT is defined as:
#define OBJC_EXPORT OBJC_EXTERN OBJC_VISIBLE
And OBJC_EXTERN is either extern "C" or extern, depending on if you're compiling C++ or C, respectively.
And OBJC_VISIBLE is either __declspec(dllexport) or __declspec(dllimport) on Windows, or __attribute__((visibility("default")) otherwise.
Basically it's saying you can link that symbol externally.
Here's the full listing:
#if !defined(OBJC_EXTERN)
# if defined(__cplusplus)
# define OBJC_EXTERN extern "C"
# else
# define OBJC_EXTERN extern
# endif
#endif
#if !defined(OBJC_VISIBLE)
# if TARGET_OS_WIN32
# if defined(BUILDING_OBJC)
# define OBJC_VISIBLE __declspec(dllexport)
# else
# define OBJC_VISIBLE __declspec(dllimport)
# endif
# else
# define OBJC_VISIBLE __attribute__((visibility("default")))
# endif
#endif
#if !defined(OBJC_EXPORT)
# define OBJC_EXPORT OBJC_EXTERN OBJC_VISIBLE
#endif
If you have three class named A,B and C respectively and all three classes are unrelated(i mean not in inheritance hierarchy) and you just want to access the value declared in A, then extern is a more appropriate way to go. In this case, you want to declare the variable as extern in ClassA.h, then define it in Class.m. As long as ClassB and ClassC import ClassA.h, they will be able to link against the same extern definition.
Instead of using extern by itself, it's more robust to use OBJC_EXPORT, which is defined in objc-api.h and handles compiling under C++ as well. Here's a code sample:
// ClassA.h
OBJC_EXPORT NSString* commonString;
...
// ClassA.m
NSString* commonString = #"OldValue";
// ClassB.m
#import "ClassA.h"
...
commonString = #"NewValue"; // Can be inside a function or method
Reference : this so post

Accessing <objc/runtime.h> from Cycript

I wan't to be able to use associated objects and ISA swizzle, but I can't figure out how to import objc/runtime.h for use with Cycript. I have tried in both the console and in .js files but no luck.
Ideally I'd like to figure out how to include frameworks as well.
It seems like a subset of runtime.h is included by default in the Cycript environment. For example, class_copyMethodList and objc_getClass work without any added effort.
var count = new new Type(#encode(int));
var methods = class_copyMethodList(objc_getClass("NSObject"), count);
However objc_setAssociatedObject is not referenced:
objc_getAssociatedObject(someVar, "asdf")
#ReferenceError: Can't find variable: objc_getAssociatedObject
After a lot of searching, I realized the answer was right under my nose. limneos's weak_classdump uses the runtime to do it's dump and Cycript's tutorial shows how to grab C functions.
The solution I ended up with is this:
function setAssociatedObject(someObject, someValue, constVoidPointer) {
SetAssociatedObject = #encode(void(id, const void*, id, unsigned long))(dlsym(RTLD_DEFAULT, "objc_setAssociatedObject"))
SetAssociatedObject(someObject, constVoidPointer, someValue, 1)
}
function getAssociatedObject(someObject, constVoidPointer) {
GetAssociatedObject = #encode(id(id, const void*))(dlsym(RTLD_DEFAULT, "objc_getAssociatedObject"))
return GetAssociatedObject(someObject, constVoidPointer)
}
It is used like this:
# create void pointer (probably should be a global variable for later retrieval)
voidPtr = new new Type(#encode(const void))
someVar = [[NSObject alloc] init]
setAssociatedObject(someVar, #[#"hello", #"world"], voidPtr)
getAssociatedObject(someVar, voidPtr)
# spits out #["Hello", "World"]

NS_OPTIONS Bitmask Autogeneration

I have a large enum (for the sake of transparency 63 values), and I am now creating a NS_Options bitflag based on that enum. Is there a way that I can write this so that it will be flexible?
The main concerns I have with hardcoding it are:
If I add/remove an enum, I will have to manually add/remove it in my bitflag.
There is a lot of typing to generate these.
My .h file is getting intensely long (because I like to use whitespace and adequate comments)
The only solution I've come up with thus far is:
#define FlagForEnum(enum) 1 << enum
typedef NS_ENUM(NSInteger, ExampleEnum)
{
Value1,
Value2,
...
ValueN
}
typedef NS_OPTIONS(NSNumber, ExampleEnumFlags)
{
Value1Flag = FlagForEnum(Value1),
Value2Flag = FlagForEnum(Value2),
...
ValueNFlag = FlagForEnum(ValueN)
}
This is a barely adequate solution when I remove an enum (at least I get a compile error), and if the enum ordering gets changed, the flags' bitshifted position changes too (not that it truly matters, but it seems comforting). But it doesn't solve the 'this-is-a-lot-of-typing' problem, or the 'what-if-I-forget-to-add-a-flag' problem.
You can use a technique called X Macro
#define VALUES \
VALUE_LINE(Value1) \
VALUE_LINE(Value2) \
VALUE_LINE(Value3)
typedef NS_ENUM(NSUInteger, ExampleEnum)
{
#define VALUE_LINE(x) x,
VALUES
#undef VALUE_LINE
}
typedef NS_OPTIONS(NSUInteger, ExampleEnumFlags)
{
#define VALUE_LINE(x) x##Flag = 1 << x,
VALUES
#undef VALUE_LINE
}
Here is a slightly better (in terms of less typing) preprocessor #define solution. Although this still isn't as elegant as I'd like.
#define BitShift(ENUM_ATTRIBUTE) (1 << ENUM_ATTRIBUTE)
#define CreateEnumFlag(ENUM_ATTRIBUTE) ENUM_ATTRIBUTE##Flag = BitShift(ENUM_ATTRIBUTE)
typedef NS_ENUM(NSUInteger, ExampleEnum)
{
Value1,
Value2,
...
ValueN
}
typedef NS_Options(NSUInteger, ExampleEnumFlags)
{
CreateEnumFlag(Value1),
CreateEnumFlag(Value2),
...
CreateEnumFlag(ValueN)
}
This will create flags of the form Value1Flag, Value2Flag, ..., ValueNFlag.

Read lua interface

In lua, is there any way to read an interface file to extract name/methods/args?
I have an .idl file like this:
interface
{
name = myInterface,
methods = {
testing = {
resulttype = "double",
args = {{direction = "in",
type = "double"},
}
}
}
This is equal to the code bellow (easier to read):
interface myInterface {
double testing (in double a);
};
I can read file, load as string and parse with gmatch for example to extract information, but is there any easy mode to parse this info?
At the end i want something (a table for example) with the interface name, their methods, result types and args. Just to know the interface that i`m working.
Lua has several facilities to interpret chunks of code. Namely, dofile, loadfile and loadstring. Luckily, your input file is almost valid Lua code (assuming those braces were matched). The only thing that is problematic is interface {.
All of the above functions effectively create a function object with a file's or a string's contents as their code. dofile immediately executes that function, while the others return a function, which you can invoke whenever you like. Therefore, if you're free to change the files, replace interface in the first line with return. Then you can do:
local interface = dofile("input.idl")
And interface will be a nice table, just as you have specified it in the file. If you cannot change those files to your liking, you will have to load the file into the string, perform some string manipulation (specifically, replace the first interface with return) and then use loadstring instead:
io.input("input.idl")
local input = io.read("*all")
input = string.gsub(input, "^interface", "return") -- ^ marks beginning of string
local f = loadstring(input)
local interface = f()
In both cases this is what you will get:
> require"pl.pretty".dump(interface)
{
name = "myInterface",
methods = {
testing = {
args = {
{
type = "double",
direction = "in"
}
},
resulttype = "double"
}
}
}
> print(interface.methods.testing.args[1].type)
double
EDIT:
I just realised, in your example input myInterface is not enclosed in " and therefore not a proper string. Is that also a mistake in your input file or is that what your files actually look like? In the latter case, you would need to change that as well. Lua is not going to complain if it's a name it doesn't know, but you also won't get the field in that case.

What this cast and assignment is all about?

I am reading Richard Stevens' Advance Programming in unix environment.
There is a code in thread synchronization category (chapter - 11).
This is code showing is showing how to avoid race conditions for many shared structure of same type.
This code is showing two mutex for synch.- one for a list fh (a list which keep track of all the foo structures) & f_next field and another for the structure foo
The code is:
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#define NHASH 29
#define HASH(fp) (((unsigned long)fp)%NHASH)
struct foo *fh[NHASH];
pthread_mutex_t hashlock = PTHREAD_MUTEX_INITIALIZER;
struct foo {
int f_count;
pthread_mutex_t f_lock;
struct foo *f_next; /* protected by hashlock */
int f_id;
/* ... more stuff here ... */
};
struct foo * foo_alloc(void) /* allocate the object */
{
struct foo *fp;
int idx;
if ((fp = malloc(sizeof(struct foo))) != NULL) {
fp->f_count = 1;
if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
free(fp);
return(NULL);
}
idx = HASH(fp);
pthread_mutex_lock(&hashlock);
///////////////////// HERE -----------------
fp->f_next = fh[idx];
fh[idx] = fp->f_next;
//////////////////// UPTO HERE -------------
pthread_mutex_lock(&fp->f_lock);
pthread_mutex_unlock(&hashlock);
/* ... continue initialization ... */
pthread_mutex_unlock(&fp->f_lock);
}
return(fp);
}
void foo_hold(struct foo *fp) /* add a reference to the object */
.......
The doubt is
1) What is HASH(fp) pre-processor doing?
I know that it is typecasting what is fp store and then taking its modulo. But, in the function foo_alloc we are just passing the address of newly allocated foo structure.
Why we are doing this I know that this will give me a integer between 0 and 28 - to store in array fh. But why are we taking modulo of an address. Why there is so much randomization?
2) Suppose i accept that, now after this what these two lines are doing (also highlighted in the code) :
fp->f_next = fh[idx];
fh[idx] = fp->f_next;
I hope initially fh[idx] has any garbage value which i assigned to the f_next field of foo and in the next line what is happening , again the same assignment but in opposite order.
struct foo *fh[NHASH] is a hash table, and use the HASH macro as the hash function.
1) HASH(fp) calculates the index to decide where the in the fh to store fp, and it uses the address of the fp and uses the address as key to calculate the index. We can easily typecast the address to the long type.
2) Use the linked list to avoid the hash collisions called separate chaining, and I think the following cod is right, and you can check it in the book :
fp->f_next = fh[idx];
fh[idx] = fp;
insert the fp element to the header of the linked list fh[idx], and the initial value of the fh[idx] is null.

Resources