How to add instance variables or properties to an XCTestCase? - objective-c

I just learned, that I must declare instance variables and properties in a header file in Objective-C. So now i want to add instance variables to my XCTestCase subclass — but it turns out, XCTestCases come without header files.
How do i declare instance variables in my test cases?

You don't have to declare them in the header file at all. Instance variables and properties are commonly added within a private category in the implementation file:
#interface MyClass () {
BOOL _someVar;
}
#property NSString *someOtherVar;
- (void)_aPrivateMethod:(id)something;
#end
#implementation MyClass
...
#end

Related

Objective-C: Different ways of declaring private variables. Any differences between them?

I have thought of different ways of declaring private variables. I want to know whether there are any differences between them.
First way:
//In .h file
#interface DataExtract : NSObject
{
#private
double test;
}
Second way:
//In .m file. test is not declared in .h file
static double test;
Third way:
//In .m file. test is not declared in .h file
double test;
Any help would be much appreciated. Thank you.
All of them are not a good solution if you want an ivar.
I would even tend to only use properties with autogenerated ivars in an class extension in the implementation file only one line (#synthesize is automatically generated in Objective-C 3.0).
First way:
Yes this is an ivar, but you shouldn't declare it in the header file, if you declare it #private, then use the #implementation {...} block. In the implementation block you don't need to declare it #private, because it defaults to #protected, but in the implementation block it is not visible for subclasses
Second way:
That is a variable only visible in the translation unit, here the .m file itself. It is not global for the whole app. The value is persistent for every instance of your class, so it is no ivar (instance variable).
Third way:
That is also no ivar, it is a variable which defaults to extern, because you did not write static. That means it is in the global symbol table and can be used in other translation units /files if they #import/#include the .m file.
Your second and third examples are not instance variables, but global variables (with differing scope) and the same value will be shared across the entire process.
You can declare a private #interface in the .m file.
//DataExtract.m
#interface DataExtract ()
//your variables
#end
#implementation DataExtract
#end
For more info you can go here
Is there a reason you want to use just an instance variable, instead of a property?
You can declare a private property like so:
// Private Interface in .m file
#interface DataExtract()
#property (nonatomic) double test;
#end
Edit:
If you do want to use a private ivar, instead of a property, you could do it like so:
// Private Interface in .m file
#interface DataExtract() {
double test;
}
#end

Can the ivar variable created automatically by properties accessible by the child class? [duplicate]

Since recent runtimes in iOS, we are able to define properties that will generate accessors for instance variables. From what I understand, it is not mandatory to declare the instance variable used since it will be automatically done for us.
For example, if I write:
#interface MyFirstClass
#property (readonly, nonatomic) int size;
#end
and in the .m
#implementation MyFirstClass
#synthesize size;
#end
Then an instance variable named "size" will be added for me and a method called "-(int)size" will be implemented.
The problem is that when I create a second class MySecondClass which is a subclass of MyFirstClass, it seems that I can't access the instance variable size within this subclass:
#interface MySecondClass : MyFirstClass
#end
#implementation MySecondClass
- (id)init {
if (self = [super init]) {
size = 10; // this yields and error
}
return self;
}
#end
Are the automatically created instance variables private? Is there a possibility to set them as protected so I can access them in subclasses?
I know there is the possibility to declare the instance variable myself, but I'm just wondering...
With a superclass like this it works: (Is it because it's expressly declared as protected?)
#interface MyFirstClass {
int size; // defined expressly and used as #protected
}
#property (readonly, nonatomic) int size;
#end
Thank you for your help!!
Nicolas.
Any instance variable not declared in the main interface is automatically private, and this cannot be overridden. If you try to use a scope modifier when defining instance variables in the implementation, you will get an error that the specification is inconsistent.
The reason for this is that there is usually only one class per implementation file, which means the compiler doesn't know about the instance variable when compiling other classes. If you have multiple classes in the same file, the compiler could know about it, but you still aren't allowed to override the scope. Possible reasons in this case could be for consistency, or just so the compiler doesn't have to look in so many places for instance variables.
Use:
self.size = 10;
That will map to setSize method.

Declaring in Objective-C

I am very new to Objective-C programming, and I have a question that has always puzzled me: why do you have to declare your variables in the header file, like this?
#interface MyViewController : UIViewController
{
NSString *myString;
}
Why not just declare them here (in the .m file):
#implementation MyViewController
- (void)viewDidLoad
{
NSString *myString;
}
The first declaration is a instance variable available to all instance methods. The second is local to the one method.
However it is possible to declare instance variables in the .m file:
#implementation MyViewController {
NSString *myString;
}
In fact this is the preferred way to declare instance variables that do not need to be exposed. Only declare things in the .h file that need to be available to other classes.
There are two different questions going on here.
To put it simply, the header file (.h) is a public gateway for everything else to see what your class is about without having to know anything about your implementation. Your header file should contain everything that you would want other classes to know about (i.e. public methods, properties).
You could easily declare things in the implementation file but then other classes would not know about them.
Secondly, in the example you provided you have put NSString *myString; in the viewDidLoad method. This means that such a variable would be only available in the scope of that method. Nothing else would be able to access it.

Best way to define private variables in Objective-C

I want to define private instance variables in MyClass.m file. It seems to me there are two ways to do it:
use class extension
#interface HelloViewController ()
{
int value;
}
define in #implementation section
#implementation HelloViewController
{
int value;
}
Which is better?
I think recent Apple's coding style is to use class extension?
e.g. MasterViewController.m generated by 'Master-Detail Application Template'
#interface MasterViewController () {
NSMutableArray *_objects;
}
#end
The "Modern Objective-C" way to do this is to declare them in your implementation block, like this:
#implementation ClassName {
int privateInteger;
MyObject *privateObject;
}
// method implementations etc...
#end
See this earlier post of me with more details.
#interface HelloViewController ()
{
#private //optional, this is old style
int vale;
}
If you were making a library, though, theoretically no one would know about any methods you didn't declare in the header files.
Copied from: How to make a real private instance variable?
Declaring instance variables in the #implementation is a recent
feature of Obj-C, this is why you see a lot of code with them in the
#interface - there was no other choice.
If you are using a compiler which supports declaring instance
variables in the implementation declaring them there is probably the
best default - only put them in the interface if they need to be
accessed by others.
Instance variables declared in the implementation are implicitly
hidden (effectively private) and the visibility cannot be changed -
#public, #protected and #private do not produce compiler errors (with
the current Clang at least) but are ignored.
Copied from: Private ivar in #interface or #implementation
In my view the best is to define it like private properties that you can access as fields or properties just within your implementation, the advatage is that you can access them by self as well as by _fieldName syntax what is handy in some situations.
#interface SignUpController ()
#property ViewHeaderView*header; //private properties/fields
#property UITextField*activeField;
#property CGFloat keyboardHeight;
#end
#implementation SignUpController {
}
#end

Difference between #interface definition in .h and .m file

Normally we use
#interface interface_name : parent_class <delegates>
{
......
}
#end
method in .h file and in .m file we synthesis the properties of variables declared in .h file.
But in some code, this #interface.....#end method is kept in the .m file also. What does it mean? What is the difference between them?
Also give some words about getters and setters for the interface file that is defined in .m file...
It's common to put an additional #interface that defines a category containing private methods:
Person.h:
#interface Person
{
NSString *_name;
}
#property(readwrite, copy) NSString *name;
-(NSString*)makeSmallTalkWith:(Person*)person;
#end
Person.m:
#interface Person () //Not specifying a name for the category makes compiler checks that these methods are implemented.
-(void)startThinkOfWhatToHaveForDinner;
#end
#implementation Person
#synthesize name = _name;
-(NSString*)makeSmallTalkWith:(Person*)person
{
[self startThinkOfWhatToHaveForDinner];
return #"How's your day?";
}
-(void)startThinkOfWhatToHaveForDinner
{
}
#end
The 'private category' (the proper name for a nameless category is not 'private category', it's 'class extension') .m prevents the compiler from warning that the methods are defined. However, because the #interface in the .m file is a category you can't define ivars in it.
Update 6th Aug '12: Objective-C has evolved since this answer was written:
ivars can be declared in a class extension (and always could be - the answer was incorrect)
#synthesize is not required
ivars can now be declared in braces at the top of #implementation:
that is,
#implementation {
id _ivarInImplmentation;
}
//methods
#end
The concept is that you can make your project much cleaner if you
limit the .h to the public interfaces of your class, and then put
private implementation details in this class extension.
when you declare variable methods or properties in ABC.h file , It
means these variables properties and methods can be access outside the
class
#interface Jain:NSObject
{
NSString *_name;
}
#property(readwrite, copy) NSString *name;
-(NSString*)makeSmallTalkWith:(Person*)jain;
#end
#Interface allows you to declare private ivars, properties and
methods. So anything you declare here cannot be accessed from outside
this class. In general, you want to declare all ivars, properties and
methods by default as private
Simply say when you declare variable methods or properties in ABC.m
file , It means these variables properties and methods can not be
access outside the class
#interface Jain()
{
NSString *_name;
}
#property(readwrite, copy) NSString *name;
-(NSString*)makeSmallTalkWith:(Person*)jain;
#end
you can even create other classes in .m file,
for instance other small classes which inherit from the class declared in .h file but having some slight different behaviour.
You could use this in a factory pattern