I am trying to make some reusable blocks for my application.
CommonBlocks.h
void (^testBlock)(int) = ^(int number) {
// do nothing for now;
};
VariousImplementationFile.m
#import "CommonBlocks.h"
(void)setup {
testBlock(5);
}
Unfortunately, when I try to push this code to iOS device I receive error: linker command failed with exit code 1 (use -v to see invocation). It seems that I missing some.
Any advice?
Thanks
You try add static keyword before the declaration:
static void (^testBlock)(int) = ^(int number) {
// do nothing for now;
};
Your code causes error because you have non-static variable testBlock declared in .h header file.
When you call #import "CommonBlocks.h" in VariousImplementationFile.m, testBlock is declared once. Then you import CommonBlocks.h in some where else, testBlock is declared once more, so you'll get symbol duplicate error.
Declare block in CommonBlocks.h this way
typedef void (^RCCompleteBlockWithResult) (BOOL result, NSError *error);
Then you may use in any method for example:
-(void)getConversationFromServer:(NSInteger)placeId completionBlock:(RCCompleteBlockWithResult)completionBlock
This is not specific to blocks. Basically, you want to know how to have a global variable that is accessible from multiple files.
Basically, the issue is that in in C, each "symbol" can only be "defined" once (it can be "declared" multiple times, but just be "defined" once). Thus, you cannot put the "definition" of a symbol in a header file, because it will be included in multiple source files, so effectively, the same symbol will be "defined" multiple times.
For a function, the prototype is declaration, and the implementation with the code is the definition. You cannot implement a function in a header file for this reason. For a regular variable, writing the name and type of the variable is defining it. To only "declare" it, you need to use extern.
It is also worth mentioning static. static makes a variable local to a particular source file. That way, its name won't interfere with variables with the same name elsewhere. You can use this to make global variables that are "private" to a particular file. However, that is not what you are asking for -- you are asking for the exact opposite -- a variable that is "public", i.e. shared among files.
The standard way to do it is this:
CommonBlocks.h
extern void (^testBlock)(int); // any file can include the declaration
CommonBlocks.m
// but it's only defined in one source file
void (^testBlock)(int) = ^(int number) {
// do nothing for now;
};
Related
I am writing some functions for a C extension module for python and need to import a module I wrote directly in python for access to a custom python type. I use PyImport_ImportModule() in the body of my C function, then PyObject_GetAttrString() on the module to get the custom python type. This executes every time the C function is called and seems like it's not very efficient and may not be best practice. I'm looking for a way to have access to the python custom type as a PyObject* or PyTypeObject* in my source code for efficiency and I may need the type in more than one C function also.
Right now the function looks something like
static PyObject* foo(PyObject* self, PyObject* args)
{
PyObject* myPythonModule = PyImport_ImportModule("my.python.module");
if (!myPythonModule)
return NULL;
PyObject* myPythonType = PyObject_GetAttrString(myPythonModule, "MyPythonType");
if (!myPythonType) {
Py_DECREF(myPythonModule);
return NULL;
}
/* more code to create and return a MyPythonType instance */
}
To avoid retrieving myPythonType every function call I tried adding a global variable to hold the object at the top of my C file
static PyObject* myPythonType;
and initialized it in the module init function similar to the old function body
PyMODINIT_FUNC
PyInit_mymodule(void)
{
/* more initializing here */
PyObject* myPythonModule = PyImport_ImportModule("my.python.module");
if (!myPythonModule) {
/* clean-up code here */
return NULL;
}
// set the static global variable here
myPythonType = PyObject_GetAttrString(myPythonModule, "MyPythonType");
Py_DECREF(myPythonModule);
if (!myPythonType) {
/* clean-up code here */
return NULL;
/* finish initializing module */
}
which worked, however I am unsure how to Py_DECREF the global variable whenever the module is finished being used. Is there a way to do that or even a better way to solve this whole problem I am overlooking?
First, just calling import each time probably isn't as bad as you think - Python does internally keep a list of imported modules, so the second time you call it on the same module the cost is much lower. So this might be an acceptable solution.
Second, the global variable approach should work, but you're right that it doesn't get cleaned up. This is rarely a problem because modules are rarely unloaded (and most extension modules don't really support it), but it isn't great. It also won't work with isolated sub-interpreters (which isn't much of a concern now, but may become more more popular in future).
The most robust way to do it needs multi-phase initialization of your module. To quickly summarise what you should do:
You should define a module state struct containing this type of information,
Your module spec should contain the size of the module state struct,
You need to initialize this struct within the Py_mod_exec slot.
You need to create an m_free function (and ideally the other GC functions) to correctly decref your state during de-initialization.
Within a global module function, self will be your module object, and so you can get the state with PyModule_GetState(self)
I'm creating a word game and I need to assign coins to a user:
firstly I've read over and over on subjects "Global variables" Unfortunately i'm not able to successfully do them.
I need to make 3 bool global variable such as btn1Pressed,btn2Pressed,btn3Pressed.
& how to make the word "coins" global of type int as well?
How is this done?
#interface MainView :
To declare global variables, you need to declare them outside of any class definition. If I have a lot of global variables, I usually put them in their own source file and call it globals.m to help keep things organized. If I only have one or two, I just declare them in the App delegate (after the #includes but before the #implementation).
int coins;
BOOL btn1Pressed;
BOOL btn2Pressed;
BOOL btn3Pressed;
// etc
Then you declare them in a common header (I use globals.h) as extern. Declare them outside of any class definition:
extern int coins;
extern BOOL btn1Pressed;
extern BOOL btn2Pressed;
extern BOOL btn3Pressed;
...
That tells the compiler that "this variable is declared elsewhere", so it knows to resolve it at link time. Include that header in any source module that needs access to those variables.
Using the keyword "extern" you can make variables global.
extern int coins = 9001; //over nine thousand!
If you mean "globals" as in "accessible everywhere in your app", you can use singletons:
http://www.galloway.me.uk/tutorials/singleton-classes/
This way you can group all such global variables in one global object.
Using Singleton pattern is the ideal way to do it.
Create your properties in YourAppdelegate.h file for your bools btn1Pressed,btn2Pressed,btn3Pressed.Further synthesize them in YourAppdelegate.m file.
Now if you want to access or change these values in any other classes
// Accessing btn1Value
BOOL checkTheValueOFButton1 = [(YourAppDelegate *)[UIApplication sharedApplication]btn1Pressed];
If you want to change the value
[(YourAppDelegate *)[UIApplication sharedApplication]setbtn1Pressed:NO];
I wish to have the sub-classes of a super-class "registered" by an arbitrary name - whenever I declare a sub-class I wish to also have it entered into the super-class.sub Map.
Is there any way to accomplish this outside of main()?
// base class
class Mineral{
final String formula;
static Map<String,Mineral> sub = {}
Mineral( this.formula );
}
// sub class - declare and register
class Mica extends Mineral{
Mica( String formula ) : super( formula );
}
Mineral.sub['mica'] = Mica; // oops!
when I run this, I get
Error: line 10 pos 1: unexpected token 'Mineral' Mineral.sub['mica'] = Mica;
assuming that executable code is not allowed outside main().
cannot put within the super-class since other sub-classes may declared later, outside the library.
Dart has no way to run code as part of a library being loaded.
Executable code can only be put inside methods, or in field initializers, and static field initializers are lazy so they won't execute any code until you try to read them.
This is done to ensure quick startup - a Dart program doesn't have to execute any code before starting the main library's "main" method.
So, no, there is no way to initialize something that isn't constant before main is called.
Either
Mineral.sub['mica'] = new Mica();
or
static Map<String,Type> sub = {};
When you assign Mica you assign the Type Mica. new Mica() is an instance of Mica that is of the kind Mineral and can be assigned to the map you declared.
edit
Maybe you want to initialize the sub map:
static Map<String,Mineral> sub = {'mica': new Mica()};
hint: the semicolon is missing in this line in your question.
I'm new to dart, and trying to use dart to write a hello world and a unit test, but I get the error:
duplicate top-level declaration 'METHOD main' at ../app.dart::5:6
My project dir is test-dart, and it has 3 files.
test-dart/models.dart
class User {
hello(String name) {
print("Hello, ${name}");
}
}
test-dart/app.dart
#library("app");
#source("./models.dart");
void main() {
new User().hello("app");
}
test-dart/test/test.dart
#library("test");
#import("../app.dart");
void main() {
print("hello, test");
}
Now there is an error in "test.dart" on void main(), the error message is:
duplicate top-level declaration 'METHOD main' at ../app.dart::5:6
The two main() methods are in different libraries, why they are still duplicated? How to fix it?
If you import a library like this #import('../app.dart), then all names from app.dart become visible in the importing code (all public names, actually -- those that don't start with a _). So in your test.dart library, you now have two main functions visible. That is obviously a collision. There are two ways to solve it (that I know of).
First: import the library with a prefix, like this: #import('../app.dart', prefix: 'app'). Then, all public names from app.dart are still visible, but only with an app prefix, so the main function from app.dart is only accessible by app.main. No collision here, but you have to use a prefix everytime.
Second: using a show combinator, like this: #import('../app.dart', show: ['a', 'b']). Then, it is no longer true that all names from app.dart are visible, only those explicitly named (a and b here). I'm not sure if this is already implemented, though.
Maybe in the future, we will get something opposite to the show combinator, so that you could do #import('../app.dart', hide: ['main']). That would be the best solution for your problem, but it isn't in the current language (as specified by 0.09).
You are importing app.dart without a prefix which means that the symbols of the importing and imported library can collide if there are duplicates such as in your example.
To resolve these collisions the library import allows you to prefix imports with an identifier. Your example should work if you change test.dart as follows:
#library("test");
#import("../app.dart", prefix: "app");
void main() {
print("hello, test");
app.main();
new app.User().hello("main");
}
Notice how the classes and top-level functions in the app.dart library are now accessed using the "app" prefix and thus do not collide with the names in test.dart.
I can't understand how to define default values for functions in my library. Default values tend to be ignored and I get "wrong parameters count" error message.
Here is my example. I created simple test library experts\libraries\test.mq4:
void test(int i = 0) // Note the default value for "i"
{
}
Then I created .mqh file as experts\include\test.mqh:
#import "test.ex4"
void test(int i = 0); // Note the default value for "i"
#import
Now I create simple expert "experts\simpletest.mq4":
#include <test.mqh>
int start()
{
// Should be able to call test() function without providing any arguments,
// because it has default value.
// If I change this line to test(0), everything compiles correctly
test(); // Causes "wrong parameters count" compilation error
return(0);
}
And I get the following error for test() function call:
')' - wrong parameters count
If I change this function call to test(0), everything compiles, but I should be able to call test() function without providing any parameters, because I have default value for first parameter in .mqh file, like this: void test(int i = 0);
Why it doesn't use the default value?
I search google for any clue, but can't find any references about this problem. Anybody knows?
This is not possible as stated in the MQL Documentation:
MQL4-library functions imported within other modules cannot have parameters initialized by default values.