I have a set of .less files
these are imported in theme.less likes this
#import "a.less";
#import "b.less";
#import "c.less";
and compiles to theme.css
I got 2 less files which defines same variables with different values.
vars_blue.less
vars_green.less
this is for theming. a.less,b.less & c.less refer these variables.
If I import vars_blue.less in above 3 less files, i will get blue theme.
I am trying to create a dynamic theme but avoiding include of variables in above 3 files, instead in theme.less
#import "vars_blue.less";
#import "a.less";
#import "b.less";
#import "c.less";
since variables are used in 3 child .less files above is not supported.
its expecting to import in each .less file where its used.
How to create 2 theme.less like
theme_blue.less
#import "vars_blue.less";
#import "a.less";
#import "b.less";
#import "c.less";
and
theme_green.less
#import "vars_green.less";
#import "a.less";
#import "b.less";
#import "c.less";
I'm don't know how to use less so my answer could be very bad.
In these kind of case how about making it this way :
you create a theme_vars.less containing only :
#import "vars_green.less";
or
#import "vars_blue.less";
then in a.less, b.less and c.less your start by :
#import "theme_vars.less";
this way when you need to change theme, only theme_vars.less need to be modified
(kinda like an abstract factory design pattern)
Related
I am new to objective-c and I want to have two interface
I am trying to reduce peer-dependency in my code so I moved .m files and am creating single .h files
I did this
#interface XyzHelper : NSObject <RCTBridgeModule>
+ (bool)isFlaggedAsRequested:(NSString * _Nonnull)handlerId;
+ (void)flagAsRequested:(NSString * _Nonnull)handlerId;
#end
#interface XyzHelper : RCTEventEmitter <RCTBridgeModule, AVAudioPlayerDelegate>
but it says Duplicate interface definition which makes sense
Any idea how I can fix it?
What I am doing?
I am creating a libraries which use
https://github.com/react-native-webrtc/react-native-incall-manager
and
https://github.com/zoontek/react-native-permissions
I don't want user to npm install both repo (and other repo's I might have) instead a single repo npm install xyz
react-native-permissions uses
#interface XyzHelper : RCTEventEmitter <RCTBridgeModule, AVAudioPlayerDelegate>
and
in-call manager have this
#interface XyzHelper : NSObject <RCTBridgeModule>
+ (bool)isFlaggedAsRequested:(NSString * _Nonnull)handlerId;
+ (void)flagAsRequested:(NSString * _Nonnull)handlerId;
#end
#interface XyzHelper : RCTEventEmitter <RCTBridgeModule, AVAudioPlayerDelegate>
what did I tried?
I tried creating a common interface
#interface XyzHelper : RCTEventEmitter <RCTBridgeModule, AVAudioPlayerDelegate>
+ (bool)isFlaggedAsRequested:(NSString * _Nonnull)handlerId;
+ (void)flagAsRequested:(NSString * _Nonnull)handlerId;
#end
but this gives duplicate symbol for a architecture x86_64
#interface XyzHelper is declared twice. Of course this is a Duplicate interface definition. Instead you could extend your XyzHelper class. In Objective-C often refered to as so called category. Given a class like the following..
NS_ASSUME_NONNULL_BEGIN
#interface XyzHelper : RCTEventEmitter <RCTBridgeModule>
+ (bool)isFlaggedAsRequested:(NSString *)handlerId;
+ (void)flagAsRequested:(NSString *)handlerId;
#end
NS_ASSUME_NONNULL_END
The extension could look like the following example. It does not only extend XyzHelper, it also declares it conforms to an extra protocol.
#interface XyzHelper (SomeAudioPlayerExtension) <AVAudioPlayerDelegate>
#end
But keep in mind when doing so you have to check if your class object conforms to a particular protocol when you want to call extra protocol methods from within the former class implementation. Why? Because the extension suggests you conform to protocol while the needed methods are maybe not available, in example the extension implementation could not be loaded or you just forgot to implement them (missing symbols). Or it was just not linked. It is anyway safer to check for conformity at least once before calling any protocol method.
Typically the file names should express they contain extended code by naming them after the classname plus extensionname. So: XyzHelper+SomeAudioPlayerExtension.h and XyzHelper+SomeAudioPlayerExtension.m
I don't know why, but after a while working without problems I added some buttons, then I launched my app and this error appeared:
ld: duplicate symbol _x in
/Users/alexbarco/Library/Developer/Xcode/DerivedData/RecolectaDatos-ayjpqqcajbhuzvbkvernzsyunpbe/Build/Intermediates/RecolectaDatos.build/Debug-iphonesimulator/RecolectaDatos.build/Objects-normal/i386/SeconViewController.o
and
/Users/alexbarco/Library/Developer/Xcode/DerivedData/RecolectaDatos-ayjpqqcajbhuzvbkvernzsyunpbe/Build/Intermediates/RecolectaDatos.build/Debug-iphonesimulator/RecolectaDatos.build/Objects-normal/i386/ViewController.o
for architecture i386 clang: error: linker command failed with exit
code 1 (use -v to see invocation)
Whenever I have duplicate symbol errors, it is almost always because I have a circular #import in my headers. The solution is quite simple, use forward declarations where possible, and #import .h files from .m files instead.
There are just two cases where you need to #import one .h from another:
if you are extending the class in the #import
you are implementing a protocol in the #import
Specifically, you do not need to import files just to use a class name or protocol in your signatures; instead use forward declarations.
For example, this (in Bar.h):
#import "Foo.h"
might become this (Bar.h):
#class Foo;
#protocol FooDelegate;
and bar.m:
#import "Foo.h"
Here is a link to the documentation on forward declarations.
The "duplicate symbol" message means that you're declaring some name (in this case, _x) twice in the same scope. Say you had code like this:
int _x = 1;
int _x = 2;
You'd expect to get an error then, right? You can use the same name for two things at the same time.
The error you're getting is essentially the same. You're declaring _x somewhere, and from the compiler's point of view you're doing it twice. There are a few ways to deal with this, depending on what _x represents.
chrahey's answer explains about forward class declarations. I won't cover that again here except to say that a forward declaration helps you resolve circular references, where the definition of class A depends on class B and vice versa.
If _x is a variable, it's likely that you're trying to declare it in a header file. The compiler basically copies the contents of each header file that you import into the source file, so if you declare a variable in a header file and then import that header into two or more implementation files, you'll end up with multiple declarations of that variable. To get around that, use the extern keyword to tell the compiler "this name will be declared somewhere else" and then put the real declaration in an implementation file:
Foo.h:
extern int _x;
Foo.m
int _x;
Pretty much the same thing goes for functions. It doesn't appear that _x is a function, but if it were, and if you were silly enough to put the function definition in a header file, then you'd again get an error if that file were imported into more than one implementation file. This is why header files contain prototypes, not definitions:
Foo.h:
int foo(int a);
Foo.m
int foo(int a)
{
return a + 10;
}
I created two classes in objective c and I would like to use one of them as a property of the other. To be more concrete, one of the classes is a 'term' that contains an integer variable and an nsstring that acts as the variable. The other class is an 'expression' that has an nsmutable array as an instance variable that contains 'terms' as its objects. What I want to do is have add the possibility of having one of the terms have an 'expression' as a property to implement something like distributing over parentheses and substituting an expression for a variable. However, Xcode is telling me that 'expression' is not an acceptable type name despite the fact that I have imported my expression header file. I think I may have read somewhere that only foundation classes are available to use as properties. What can I do to add this class as an instance variable?
I suspect you have an import cycle, like this:
Expression.h
#import "Term.h"
#interface Expression : NSObject
...
Term.h
#import "Expression.h"
#interface Term : NSObject
...
Notice how each file imports the other? That won't work. Instead, you need to use forward declarations:
Expression.h
#class Term; // tell the compiler that Term is a class name
#interface Expression : NSObject
...
Term.h
#class Expression; // tell the compiler that Expression is a class name
#interface Term : NSObject
...
Then, in your .m files, you can safely import both .h files:
Expression.m
#import "Expression.h"
#import "Term.h"
#implementation Expression
...
Term.m
#import "Term.h"
#import "Expression.h"
#implementation Term
...
Although the above answers are also correct, in my case the problem which occured was "#end" was missing in prototype/interface declaration.
My question is a simple fundamental question for creating a subcategory of a category in objective-c.
Consider a file named NSString+categoryName.h given as follows:
#import <Foundation/Foundation.h>
#interface NSString (categoryName)
...
#end
with a corresponding implementation file named categoryName.m (not shown).
How would I make a subcategory if this? Here is my initial thought (contained in a separate file called NSString+categoryName+subCategoryName.h):
//Should there be an import statement here to prepare compiler for appearance of categoryName?
#import <Foundation/Foundation.h>
#interface categoryName (subCategoryName)
...
#end
possessing a separate implementation file of a similar name NSString+categoryName+subCategoryName.m:
// Is the import correct here? Do I need to somehow reference this in my .h file?
#import "NSString+categoryName.h"
#implementation categoryName (subCategoryName)
...
#end
Any help with this matter is greatly appreciated, as always!
I have never heard of a "subcategory" in Obj-C. You can create as many categories as you like for the same class, and you can adopt a naming convention like #interface Class (category_subcategory) ... #end or similar, but your idea of making a category on a category does not seem workable.
Categories are not hierarchical in Objective-C. They're just a way to put methods into groups that aren't all loaded at once.
I am new to Objective-C and want to know about inheritance. I am aware of the concepts but confused with the methods that programmer uses to inherit a class.
I have two classes: class A and class B, and want to make B a child of A.
Sometimes a programmer uses #import "class A" and sometimes uses the # sign. Which one of them should be used, and why? Is there any difference between their uses?
Another question I have is about the ":" sign which we write after class declaration, for example #interface class_A : class_name
In past I was a student of Java and C#, and their inheritance is similar to each other. But is Objective-C (I am currently working for iPhone) the same?
There is a difference between those terms, and I can see where your confusion is.
The #import is used to load definitions of a class's h file. This is, in a way, similar to C#'s using keyword, but in Objective-C we need to specify everything in the class level, not in the namespace level -- there's no concept of namespace level encapsulation in Objective-C.
The #class keyword is used whenever you need to declare that an object is valid -- but if you're going to use the internals of that object you will eventually need to add an #import of the class anyway. There's a great answer here on the difference between #class and #import.
As with C# and Java, inheritance is achieved by using the : operator in your h file. So in your declaration of Class B, it should go like:
#interface Class_B : Class_A
Hope this clears everything up.
update for your comment:
Let's say I want to inherit class A into class B, and use class C as a variable somewhere. You'll need the ff to make it work:
#import "Class_A.h"
#class Class_C;
#interface Class_B : Class_A {
Class_C *myvariable
}
Now, lets say somewhere inside your file you need to access a Class_C member e.g., myvariable.Property1, that's the time you turn #class Class_C into #import "Class_C.h".
I don't think declaring it like this:
#class Class_A;
#interface Class_B : Class_A
would work... you'll still need an #import "Class_A.h" somewhere which makes the #class declaration somewhat redundant.
if we do this
#interface Class_B : Class_A
mean we are inheriting the Class_A into Class_B, in Class_B we can access all the variables of class_A.
if we are doing this
#import ....
#class Class_A
#interface Class_B
here we saying that we are using the Class_A in our program, but if we want to use the Class_A
variables in Class_B we have to #import Class_A in .m file(make a object and use it's function and variables).