Objective C - 2 .m files for one .h file? - objective-c

My question is, that I would know how to use 2 .m files for one objectclass also for one header (.h)
I have a big method with 20000+ lines and I would, that this method stand alone in a .m file and the other methods in the other .m file. I have done it, but I get errors, that the methods aren not in the one .m file. I get a link error, but i can remove the link error if i delete the second .m file.
Is it possible to create 2 .m files for one header ?
If yes pleas tell me how?

I have a big method with 20000+ lines
Okay, that's your problem right there. That's what you need to fix. Splitting things up into two implementation files is a distraction. This is your main problem. There's virtually no circumstances where this is not a terrible way of doing things.
Methods should be a few dozen lines long at most. If you find yourself writing a method that is longer than that, you need to break the functionality down into smaller pieces. Create smaller methods to do part of the job, then call those methods from your original method.
Classes should not be this size. If you are creating a file with more than a couple of thousand lines of code in, it's a huge warning sign that one class is responsible for too much functionality. You should break the functionality down into several classes, each of which is responsible for one key piece of functionality.
I get a link error
If you post a sentence like this to Stack Overflow, it should be accompanied by the actual error you get.

You can make the excessively long method a category of the class:
MyClass.h:
#interface MyClass
#property ...
-(void) method;
...
#end
#interface MyClass (BigMethod)
-(void) bigMethod;
#end
MyClass.m:
#implementation MyClass
-(void) method
{
...
}
...
#end
BigMethod.m
#implementation MyClass (BigMethod)
-(void) bigMethod
{
...
}
#end
However, a 20k line method is absurd. You should really refactor it.

You have several approaches:
you could split your methods into 2 different categories:
//-- MyClass1.m
#implementation MyClass (part1)
#end
//-- MyClass2.m
#implementation MyClass (part2)
#end
I defined 2 categories for symmetry reason; of course you also need a "base" #implementation of your class (i.e., without the category specifier); you can choose whether you define a "base" and and extension category, or "base" and two categories, etc...
or you might try including the second .m file inside of the first one:
//-- MyClass1.m
#implementation MyClass
<first part>
#include "MyClass2.m"
#end
Both should work.
Let alone the possibility of refactoring your class, which would be the best option.

Related

Multiple #interface declarations generated by Xcode for NSViewController?

I am making a Cocoa application, and using Xcode for various code-generation. Works fine for generating .h and .m files for subclassing UIView, but when i subclass UIViewController i get an #interface declaration identical in both files, except that in the .m file it has ( ) at the end:
//in MyViewController.h
#interface MyViewController : NSViewController <MyViewDelegate>
#end
but also
//in MyViewController.m
#interface MyViewController ()
#end
#implementation MyViewController
#end
Yet it compiles fine. So, assuming this is normal behavior, the two-parts of question are:
(A) Why does this happen, and
(B) What are the results -- especially in terms of compile order?
Thanks!
when i subclass UIViewController i get an #interface declaration identical in both files, except that in the .m file it has ( )
As you noticed, the two interface blocks are not identical -- the () is important. The one with the () is a class extension, which is similar to a category without a name. The two important differences between a category and a class extension are:
You can declare instance variables in a class extension, but you can't in a category.
A class extension must appear in the same file as the implementation block.
Class extensions are useful for declaring instance variables and methods that you don't want to expose in the header file, such as methods or variables that are specific to the implementation and shouldn't be relied upon by users of the class.
Are you familiar with Categories? What you are observing is similar, but has important distinctions from Categories. The distinction here is that it is anonymous (hence the empty parens) and compiled at the same time the original class is compiled. That later part is an important part: it means you can add instance properties (storage). This is most commonly used to declare "internal only" or "private" methods and properties. But keep in mind that at runtime there is no notion of 'private' enforcement, it's all about what interface you have published vs. not published. This is just one way to have very clearly defined interface that is only 'published' to people who author the implementation file of the core class.

How to send a message from an instance method to a object of another class

I tried to search for an answer about this (simple) question but nothing seems to work well, even books are not so specific (atleast the books I've read), or probably I'm simply missing something important, since I'm a little bit confused I've decided to try here.
Here's the question:
Say that I have a ClassA which contains one or many instance variables.
Then I have a ClassB which contains an Instance Method that modify ClassA variable (is this possible right?) the classes have NOT inheritance from each other, both inherits from NSObject
Then I want to call the method of the ClassB over the ClassA object on the UIViewController. I believe I need a reference between classes but i'm not sure on how to set them to make them works. Imagine I have a Paper which contains writes or numbers (in this case numbers) and a class erase to modify it's variable and erase numbers (for example by subtracting).
here's some code:
Paper.h
#interface Paper : NSObject
#property (nonatomic) int numbers;
#end
Paper.m
#import "Paper.h"
#implementation Paper
#synthesize numbers;
#end
and Eraser.h
#interface Eraser : NSObject
-(void)eraseMethod;
#end
Eraser.m
#import "Eraser.h"
#implementation Eraser
-(void)eraseMethod {
//here I want to make a subtraction of the ivar declared in Paper
}
#end
and finally I'm trying to call it on the UIViewController like so
[paperObject eraseMethod];
I tried by declaring #class in each files as I've read somewhere but this won't help in any way... I hope this is clear as question
Ivars are just storage slots and they are private to the class when without specifying access conditions.You can use property for the purpose of accessing from another class. more info here
in order to achive what you speak of,make the method a class method
see here
#import "Eraser.h"
#implementation Eraser
+(void)eraseMethod {
//here I want to make a subtraction of the ivar declared in Paper
}
#end
thus you can achieve the method in your VC.

What to do when .h file is empty in objective c?

I have a class hierarchy where I have a super class and then a whole bunch of subclasses that extend it. The issue though is that these subclasses don't ever add new methods or properties. Instead, they just override one of the super classes methods (in essence making it abstract). This leaves the .h files for the subclasses completely empty (except for the #interface and #end lines).
What is the most appropriate action? Should I just leave these practically empty .h files or is there some better way to deal with this situation?
Just leave them empty, that's perfectly fine.
You could leave the header files blank or you could just get rid of them all together and have 1 file which has both the header and implementation, like below.
#interface BaseClass: MySuperClass {
}
#end
#implementation BaseClass
#end

Can we not declare methods in the header files?

I am watching the Stanford University iPad and iPhone application Developments course video. The instructor says in the video we can control-drag an UI object to the implementation files to create an action. But in this way the method will not declare in the header file. Does this mean it is ok to implement methods in the .m file but not declare in the .h file?
Depends on how you define "ok" :-)
Objective-C uses dynamic method lookup and does not really enforce access ("private", "public", etc.) specifiers. So you don't need to declare any method in a header file.
However you will end up fighting the compiler as it does do a fair amount of type-checking unless you persuade it not to, and you'll lose by doing so.
You are not required to declare in the header file all methods in the implementation. But if not in the header file obviously you cannot reference them by literal name in another file, nor can you "forward reference" them in the implementation file.
(Note that this is not that different from regular C, but is different from methods of a class in C++.)
It's "OK" to not declare methods in the header yes, under certain circumstances. For instance, if using ARC then the compiler generally needs to know the method signature so it can do the right thing. But basically all it means is that wherever you're using the method, it must already know about the method you're calling.
Since you're talking about Interface Builder, that's slightly different in that it will know about all methods since it can "see" the whole context of your header and implementation files and know that a method exists. i.e. in my terminology above, the method has been defined before it's used.
With regard to defining before use, the general accepted approach is to either:
Define a method in the interface file (.h). e.g.:
MyClass.h
#interface MyClass : NSObject
- (void)someMethod;
#end
MyClass.m
#implementation MyClass
- (void)someMethod {
// do something
}
#end
Define a method in a class continuation category. e.g.:
MyClass.h
#interface MyClass : NSObject
#end
MyClass.m
#interface MyClass ()
- (void)someMethod;
#end
#implementation MyClass
- (void)someMethod {
// do something
}
#end

What's the difference between adding pseudo-private ivars in a class extension or in the #implementation block?

What's the difference between putting pseudo-private instance variables in a class extension inside the .m file, or putting them in the newly introduced #implementation brackets like shown below?
Are there consequences, pros, cons over one or the other way? Is internal2 treated differently than internal3 in a way a programmer must care of? (of course there is a difference McKay would say but the question is if you care in practice or not).
// MyClass.m
#interface MyClass () {
id internal2;
}
#end
#implementation MyClass {
id internal3;
}
- (void)internalMethod {
NSLog(#"%# %#", internal2, internal3);
}
#end
source: http://www.mcubedsw.com/blog/index.php/site/comments/new_objective-c_features/
The main difference between the two approaches is that you can include the class extension in a separate header, whereas the #implementation ivars obviously have to go with the #implementation block in the .m file (and there can only be one #implementation for a given class (extensions not included)). The practical result of this is that you can have multiple levels of "private" ivars:
MyClass.h: public ivars
MyClass+Private.h: semi-private ivars
MyClass.m: really private ivars
As a hypothetical example, pretend that MyClass is UIView. In that case, UIView.h is the header that we can all access, UIView+Private.h is the "private" header than only Apple can access, and UIView.m has stuff that only the people specifically responsible for UIView need to know about.
Personally, I prefer to put my ivars in a single class extension in the implementation file, I think it's cleaner that way. I don't think there are any performance advantages or consequences to using one or the other, it's more about being able to code the way you want to.