I had this problem with import statements with my own classes using forward declarations to fix that. I have a method that uses type CTFramesetterRef. So I needed to add the CoreText framework. If I declare the method in my .h file, do I just
#import <CoreText/CoreText.h>
in my .h file and not my .m file. Are there any hard and fast rules for this? Sometimes I see code that has it in the .m, sometimes in the .h. To me it seems like what I see is declare it in the .m if you can, if you have to put it in the .h, put it there instead, and if you can use a forward declaration for a class, then do that. Just not sure what the proper way to do things are. Thanks.
"declare it in the .m if you can, if you have to put it in the .h, put it there instead, and if you can use a forward declaration for a class, then do that." - I would say this is the proper way to do that.
Related
I am new in iphone development and i have little bit Question.
My Question is When do we use #class and #import in .h (header )file.And if your answer is #class u can create instance but can not.. use its methods and by use of #import in .h file we can access all method and variable of second class .Then My Question is
if #import contains advantage then why many people used only #class in their .h file.
Please anybody have answer then reply asap.Thanks in Advance.
First of all, you're right with your assumption.
As for advantages:
The #class directive is faster, since it only discloses the Name, and the Inheritance to the Namespace (e.g. the Header File). But #import loads everything, so it's slower and means more load on the system. If your Code is a library for another system, its pretty useful if the headerfiles only load the classname (#class)
For an example. You have the class A, and are importing a Headerfile B from a library. B itself wants to use C. If it imports all data in the B Headerfile, it gets bloated, because you would load it too when importing the headerfile into your class A. But it isn't necessary, that your class A knows what Class C is capable of, because only B is using it.
Have you ever encountered cyclic imports,I suppose you are not.
The other answers are also correct but when it comes to cyclic imports the compiler gives error and you have to use #class instead of import.
quick example
//A.h
#import "B.h"
//B.h
#import "A.h"
In this case compiler will give you the error. So you have to use #class in one of the header files to remove cyclic import. It is true that #class is faster than #import but my projects doesn't have large amount of files that it would take hours to compile it :)
OK, trying to be more clear, then. This is what you usually want:
Use #class in your .h file if the header file doesn't need access to anything in the class you're importing (i.e. it only needs to know that the class exists in order to compile).
Use #import in your .m file to get access to the imported class' properties and methods.
An example, where your class Foo needs to use another class you've created, Bar. Bar also has a custom initializer, -initWithCustomValue:.
MyClass.h
#class Bar
...
Bar _instanceVariable;
MyClass.m
#import "Bar.h"
...
_instanceVariable = [[Bar alloc] initWithCustomValue:1];
This would make sure that you're not exposing unnecessary code (i.e. the contents of Bar) to other classes that might be importing MyClass.h.
From the Apple docs:
The #class directive minimizes the amount of code seen by the compiler
and linker, and is therefore the simplest way to give a forward
declaration of a class name. Being simple, it avoids potential
problems that may come with importing files that import still other
files. For example, if one class declares a statically typed instance
variable of another class, and their two interface files import each
other, neither class may compile correctly.
if i want to create a helper method in my .m file. its call it -(void) helpMeDoSomething... etc. do i need to declare the function prototype in the .h file like in c/c++ or just declaring it in the .m file is enough
Neither C, C++, nor Objective-C require function declarations to be in the header file. They simply have to be declared before they are used, and the definition in the .m file can serve as the declaration.
In order for other classes to see the method, its signature must be in the header file. If you are using the method in the same class that it is defined in, it does not need to be in the header file.
Put the prototype in the .h file if you want to make it available to be called from code in other files. You can put it in the .m file if it will only be called from inside that one file.
As in C/C++, you can declare it in your .m file as long as you declare it before you use it, and as long as you don't need it somewhere else.
Its kinda general question. What difference it make if we create instance of UIViewController in interface (.h) file and declare it as property and use it in implementation (.m) file to push it on current view than that of creating instance in implmentation file itself and push it on current view in UINavigationcontroller ?
Regards,
Sumit
In Interface i.e. .h file we are just having declaration of the variables and that are only the references to the class and NOT the INSTANCE... Please understand the difference between reference and instance both are different. When declaring in .h file we are agreeing that we are going to use that variable in our .m file. And we can instanciate it... Also other 2 answers are also having its own points....
Usually you define your UIViewController in .h as a field of your #interface because you may need to access it in more than one point or it can be useful, for you, to keep a pointer to that controller. If you don't need this you can simply define it in .m, use it and then release (or autorelease) it.
There are a few differences. By making it a property the code generated will have some retain/release logic built in.
Also, by declaring the field and property in your .H file, the member is effectively "public" and visible now from other classes. If you only have the member defined in your .M file, it is only accessible within your own class.
When and what methods should be declared in the #interface section of a class? As I understand, methods that describe what your class does should be declared in the #interface section, but other "helper" methods should not be declared. Is this a correct understanding from my side?
One way is to declare the instance methods in .h file. And, declare the private methods inside the .m, using a Category.
For example, in MyOwnClass.h file.
#interface MyOwnClass
- (void)aInstanceMethod;
#end
And, inside your MyOwnClass.m file, before the #implementation block,
#interface MyOwnClass (MyPrivateMethods)
- (void)aPrivateMethod;
#end
You usually should add your methods to the .h file when you want an external class to have access to it (public methods).
When they're private (only used internally by the class) just put them in your .m file.
Anyway, it's just a pattern. As Objective-C works with messages, even if you don't set a method in your .h file an external file can access it, but at least your auto-complete won't show it.
You should declare all your methods in your .h
The tip from EmptyStack is nice but it's just a tip.
If you don't intend to ship your binary as an SDK, you don't really need it.
Objective-C doesn't have (yet) private methods.
So, I read this post, and it's pretty much exactly what I was looking for. However... it doesn't work. I guess I'm not going to go with the singleton object, but rather making the array in either a Global.h file, or insert it into the _Prefix file.
Both times I do that though, I get the error:
Expected specifier-qualifier-list before 'static'
and it doesn't work. So... I'm not sure how to get it to work, I can remove extern and it works, but I feel like I need that to make it a constant.
The end goal is to have this Mutable Array be accessible from any object or any file in my project. Help would be appreciated!
This is the code for my Globals.h file:
#import <Foundation/Foundation.h>
static extern NSMutableArray * myGlobalArray;
I don't think I need anything in the implementation file. If I were to put that in the prefix file, the error was the same.
EDIT
So, I removed the .m file from Globals, and I just have the code about in Globals.h. Assuming I am going to continue with this terrible practice of having global variables (I know it's bad, I just want to test this out), I now have a new error. It says:
"Multiple storage classes in declaration specifiers"
If I remove "extern" it works and if I remove "static" it works, but having both doesn't... what now?
****Double Edit****
Aright, so I've tried adding the array to my UIApplication Delegate, but I'm doing it wrong because it isn't working. Could someone give me some example code as to where to place it an access it? I don't know if it should go in the implementation, or somewhere else, and once the array is initialized how to access it from the other files... Do I set a new variable to the array, or something?
Just a general programming suggestion--don't share an array. You have no control over it and it will be virtually impossible to trace if something changes it at a time and in a way you aren't expecting.
Instead, create an object with the array inside it and make that object a singleton (or better yet, make a factory for it).
Whenever you want to modify your array, call methods on the object to do so. If you do this, I bet you will find a lot of redundant code you can factor into this object (for instance, searching the array for a value--make a "search" method in the object instead and pass in a value).
It may seem like a lot of work you shouldn't have to do, but you'll find it's fairly fun work, and you should find that you DO have to do it once you see how much code belongs in this object...
Just add the array as a property of the application delegate, and access it like:
[[UIApplication sharedApplication] myArray];
The two (main) ways of making an array global are separate -- either you have a class with a method
static NSMutableArray *foo;
+(NSMutableArray *)foo {
return foo;
}
(in the .m file) with the static piece NOT in the header file, or just
static extern NSMutableArray * myGlobalArray;
with out the singleton wrapper (which I think is better as it saves you from having an extra bit of unnecessary code)
Either way, it is still a bad practice that I would try to avoid.
In general, the presence of a "Globals.h" file is a bad smell that there's an antipattern at work.
I would even advise against Bill K's advice and not use a Singleton pattern at all.
Instead, create the array in your app delegate, and pass it to your root view controller(s), and along the hierarchy to the components that need access to it.
This is what I was looking for:
http://derekneely.com/tag/app-delegate/
Thank you for pointing me in the right direction!
#import <Foundation/Foundation.h>
static extern NSMutableArray * myGlobalArray;
#interface Globals : NSObject {
}
#end