开发者

Objective-C: Simple question about header file declarations

开发者 https://www.devze.com 2023-04-01 02:44 出处:网络
A beginner here, developing for the iPhone, with an extremely simple questio开发者_StackOverflow中文版n: What is the reason behind declaring a method in a header file, and then filling it out in the i

A beginner here, developing for the iPhone, with an extremely simple questio开发者_StackOverflow中文版n: What is the reason behind declaring a method in a header file, and then filling it out in the implementation file? Does this always have to be done?

Also, I know to declare variables in the @interface of the header file, but why are they only sometimes repeated with the @property tag? Is this for variables that other classes may wish to read from or write to (hence why they automatically create getter and setter methods)?

Kind regards.


Declaring a method in .h file is known as forward declaration. If you declares a method header in the .h file then the compiler will know the method name, parameters and return type before the actual linking. You can write a method body only in the .m file. But that method can be used only by methods declared after it in that file. But if you declare a method in the header then it won't be a matter. Because then the method signature will be know to all during the first pass of compiler and will be linked in the second pass.

@property and @synthesize tags are used to create automated getters and setters (or Accessors and Mutators, in Objective-C terminology), but there is more. In iOS you have to do memory management manually (it should be changed in iOS5, as apple promised). In the @property tag you can tell how the memory will behave during an assignment.

iOS tracks the memory management of an object by maintaining a retain count. When you allocate an object it's retain count becomes 1. Then you can manually increase the retain count by the retain method (e.g. [myObj retain]) or decrease the retain count by the release method (e.g. [myObj release]). When the retain count falls to 0 iOS delete that object from memory. With the @property tag you can define how retain count will be manage during an assignment. For example two mostly used parameters in the @property tag are:

@property (nonatomic, retain)
@property (nonatomic, assign)

In the first case during an assignment the retain count of the object will be increased by 1 automatically (e.g. self.myObj = anotherClass.anotherObjOfSameClass;) and in the later case the retain count would not be increased.


The point of a header file in any C-language is to separate implementation from the available methods. That is, you define the template of the class in the header file so that someone using your code can just be like "oh ok I want to use this and this method and now I know how to instantiate an object of this class". It's all about abstraction. :-)


I guess it is just to make two files, one for public API(.h) and your logic and implementation in (.m) to hide from other people. also property tag helps to make getters and setters for your variable.

you use @property in header file and than @synthesize it in implementation which will let you access thru getters and setters.

More reading on,

http://developer.apple.com/library/mac/#referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/_index.html#//apple_ref/doc/uid/TP40007594

FYI you can do something like this too, But not recommendable

#import <UIKit/UIKit.h>

@interface FileSystemDemoViewController : UIViewController {

    UITextView *actorListBox;
    NSArray *dataToShow;
}

@property (nonatomic, retain) IBOutlet UITextView *actorListBox;
@property (nonatomic, retain) NSArray *dataToShow;

-(IBAction) covertToAscending:(id)sender;
-(IBAction) covertToDescending:(id)sender;

@end

@implementation
...Your implementation here...
@end

Above all code is in .m file, Implementation.

again NOT RECOMMENDABLE

Happy coding


Why separate .h and .m files?

Historically, in C, when you included a .h file, it was almost literally equivalent to pasting the file into the file that included it. Effectively, all your declarations were repeated in every file that used them. That's ok, in C you can repeat declarations all you want, as long as they don't change. However, repeating definitions would result in multiple copies of a function and general brokenness. Therefore you couldn't include the whole code of a module, only its declarations.

I think Objective-C is actually smarter, and you could if you want have no .m files at all, and put all the code in .h files. You could also define a class only in a .m file and have no .h file, but you couldn't really make a whole project like that, since nothing would be able to access anything else.

However, it's still good practice to separate declarations from definitions. It's like having a menu at a restaurant instead of having to go back into the kitchen and see what's cooking. The .h file is a short summary of how other modules can make use of a module's contents.

Why some instance variables have properties and some do not?

Correct, part of it is that instance variables aren't automatically available to other classes. Properties by default are. However, not necessarily. You can make a property private.

Another thing you get with properties is automatic memory management. If you use the retain attribute, when you assign a value to a property, the value's retain count is increased, and the previous value's retain count (if any) is decreased. It's very convenient and avoids goof-ups. Even if other classes don't access the instance variable, it's useful. If you don't use properties, you have to make sure you do the appropriate retain and release instructions within your instance methods to avoid leaking memory. There are other automatic behaviors you can get on properties too, like locking or copying.

Lastly, you can get built-in behaviors with property attributes and the @synthesize keyword, but you can also decide not to use the @synthesize keyword, and write custom getters and setters for your properties. Those can do fancy things, like update related instance variables whenever a property is changed.


As noted, the original reason for .h and .m files is that C compilers process each source file in isolation, then connect the dots between them only when they come to link. There therefore needs to be some mechanism by which declarations can propagate — so that each file individually can be checked for compiler errors and warnings — but definitions remain in a single place — so that the linker can ensure common resources end up in a common place.

As of the modern runtime, the distinction between .h files and .m files is better thought of as the difference between the interface and the implementation. The interface is something you publish for everyone to see. The implementation is something that's for the knowledge of that class only. Your only contract with the outside world is that defined by the interface.

Objective-C, like most object-oriented languages, adopts the concept of getters and setters for object properties. Objects don't have access to the instance variable of other objects, they instead ask "what's this value?" or "please set the value of that to this". Prior to Objective-C 2.0 you had to write getters and setters yourself, which introduced a whole lot of repetitious boilerplate code. The initial purpose of @property was to declare getters or setters in the interface. @synthesize is used to generate the default implementation for something declared as an @property.

As of the new runtime, there's no need to declare instance variables in the interface, you can keep them entirely within the implementation. So, for example:

SomeClass.h:

@interface SomeClass: NSObject

- (void)doSomeTask;

@end

SomeClass.m:

// declare a category with some unexposed properties
@interface SomeClass ()
@property (nonatomic, assign) NSMutableArray *arrayForMe;
@end

@implementation SomeClass

@synthesize arrayForMe; // you can now use the property self.arrayForMe,
                        // even though you didn't declare a backing
                        // instance variable

- (void)doSomePrecursorTask
{
    // ...
}

- (void)doSomeTask
{
    // as a fact of implementation, I need to do something else
    // first. Because it's an implementation specific, I don't
    // want to put it in the declared interface

    [self doSomePrecursorTask];
    // ...
}

@end

The new runtime is available on iOS, Lion and 64bit Snow Leopard. As a matter of good practice, it probably makes sense to keep instance variables out of header files now. Just put the public interface in there and think of them as a way to formalise and communicate. I would expect that instance variables in the header are going to look as old fashioned as NSEnumerator very quickly.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号