#interface and #implementation in same file (no header file, Xcode unit test template) - objective-c

Xcode generates this template code for a new Objective-C test case. Why does it not generate a header file and puts the #interface in the implementation file?
#import <XCTest/XCTest.h>
#interface BYObjCTest : XCTestCase
#end
#implementation BYObjCTest
// test methods
#end
How is this construct called? Is this a private class? Test cases are generally not needed to be called from outside of user code, is this the reason this is generated this way?

It's ok to have the interface ClassName : Superclass block (called the class declaration block) in a .m file.
Declaring a class in a Header (.h) file is more common because it's for class that needs be public (class that will be used in other class), but if your class is not meant to be used in outside of the .m file, then it's ok to have the declaration and implementation in the same .m or .mm file.
In the test of TestClass for example, they are not used anywhere else,so no need for a header.
Other language would call those private class. Well private class in objC have no .h file :)

Related

getting Swift Object from Objective C class using another Swift File

I have been trying with no success the following structure:
ClassA.swift
class ClassA:NSObject{
var varA = ""
}
then I have a ClassB.h and ClassB.m (Objective c) and I am not able to define "Project-Swift.h" in the .h file so i import it into the .m
#interface ClassB()
#property ClassA *myClassA;
#end
and
#synthesize myClassA = theAClass;
The problem comes when I try
class ClassC:NSObject{
let theClassAFromC = ClassB.myAClass
}
I get an error message Value of type 'ClassB' has no member 'theClassA'
Add your objc header to bridging header
In your objc header use #class notation for your swift class, e.g. #class ClassA;, instead of import "Project-Swift.h" file. You can import that one in your objc implementation file.
Don't forget that you cannot access non-static property of objc class the way you're declaring. Instead, initialize your ClassB object in your swift class and access it's property when needed. For instantiating the ClassA object you can use dependency injection in ClassB
As part of the convenience, use #objc declaration for your Swift classes accesible to objc runtime
try to search with keyword "Bridging-Header" and then add
#import "ClassB.h"
That does not work in my case.
adding ClassB.h in my Bridge File makes properties from .h Visible But not the the properties in my .m file. If i add Class.m In my header file then Module-Swift.h is not found

Are methods declared in categories visible to other classes

Suppose I have the following
FileName : DBManager.h
#import <Foundation/Foundation.h>
#interface DBManager : NSObject
//Notice no method is declared here
#end
Now its implementation file looks like this
FileName: DBManager.m
#import "DBManager.h"
#interface DBManager()
+ (DBManager*) SomeMethod;
#end
#implementation DBManager
+ (DBManager*) SomeMethod
{
....
return SomePtr;
}
#end
Now in some other class method if I do the following
[DBManager SomeMethod] ; //Error No known class method for selector 'SomeMethod'
However if SomeMethod is declared inside the .h file inside of category then this works fine. I wanted to know if this was a limitation of categories that the methods are not visible to other classes ?
First, #interface DBManager() is not a category, it's a class extension. There's no identifier between the parentheses.
Second, the issue isn't visibility based on whether the method is declared in a class, category, or class extension, it's whether it was declared in the same translation unit.
A translation unit is a source file after the preprocessor has included/imported the header files (or whatever other files have been included/imported).
The error is telling you that the declaration of +SomeMethod was not declared in the translation unit. If it were, there'd be no error, regardless of whether it were declared in the class interface, a category, or a class extension.
It follows that if you declare the interface of a category in a header file and include the header file in a source file, you can use the methods declared by that category in that source file.

Declaring method prototypes in header and implementation

I am learning object orientated programming from the online Stanford courses there is a part I am unsure of regarding declarations. I thought that you must always declare the prototype in the header and then write the code in the implementation file, but the professor wrote a method in the implementation without a declaration prototype in the header file, how come?
Also, may someone please clear the difference between private and public and if the method without a prototype is public or private? The method without a prototype is not from a super class.
That is a perfectly legal way to declare methods that are not to be used outside the class implementation itself.
The compiler will find methods in the implementation file as long as they precede the method in which they are used. However that will not always be the case, as the new LLVM compiler allows methods to be declared in any order and referenced from a given file.
There are a couple of different styles for declaring methods inside an implementation file:
//In the Header File, MyClass.h
#interface MyClass : NSObject
#end
//in the implementation file, MyClass.m
//Method Decls inside a Private Category
#interface MyClass (_Private)
- (void)doSomething;
#end
//As a class extension (new to LLVM compiler)
#interface MyClass ()
- (void)doSomething;
#end
#implementation MyClass
//You can also simply implement a method with no formal "forward" declaration
//in this case you must declare the method before you use it, unless you're using the
//latest LLVM Compiler (See the WWDC Session on Modern Objective C)
- (void)doSomething {
}
- (void)foo {
[self doSomething];
}
#end
If you write the method in you header file it is public and accessible for other classes / objects. If you do not declare it in the header file the method is a private method meaning that you can access it internally in you class but no other class can use this method.

Varieties of #interface declarations, some with parentheses

I've noticed a variety of #interface declarations for Objective-c classes. I'd like to understand why developers declare #interface in the following ways:
// in the .h file
#interface MyClass : NSObject
// ...
#end
// in the .m file (what's the purpose of the parens?)
#interface MyClass ()
// more property declarations which seem like they can go in the .h file
#end
// again in the .m file (what's the purpose of private?)
#interface MyClass (Private)
// some method declarations
#end
This is just a normal class interface, inheriting from NSObject, where you declare ivars, properties and methods
// in the .h file
#interface MyClass : NSObject
// ...
#end
The following two are categories, which allow you to add methods to a class. It is not a subclass however (do not declare a method with the same name, as you won't be able to access the original one). If you have a named category of the interface (like #interface MyClass (Private)), then the implementation should be provided in #implementation MyClass (Private), in the case of unnamed categories (also called extensions), the implementation can be provided as usual. Note that extensions also allow you to add ivars to the class while (named) categories do not.
// in the .m file (what's the purpose of the parens?)
#interface MyClass ()
// more property declarations which seem like they can go in the .h file
#end
// again in the .m file (what's the purpose of private?)
#interface MyClass (Private)
// some method declarations
#end
It is used to declared private methods.
This response explain this in details: What are best practices that you use when writing Objective-C and Cocoa?
What ever goes in the .m file is private. the parens are for categories so you can segment your code into categories to make it more readable. because the code is in .m and private, they called the category Private.

Cocoa: Build Warning that s Forward Declared Class's and #interface May not Exist

I am trying to build the Clustering Plug in my project under Leopard. I have following two questions.
In the project an interface class is defined as
#interface ClusteringController : NSWindowController
{
.......
.....
....
}
#end.
And this class is used in implementation class using forward declaration:
#class ClusteringController;
then in one function it is used as:
- (long) filterImage:(NSString*) menuName
{
ClusteringController *cluster = [[ClusteringController alloc] init];
[cluster showWindow:self];
return 0;
}
When I build this project it produces the warning:
warning: receiver 'ClusteringController' is a forward class and corresponding #interface may not exist
Also there is one more warning produced:
warning: no '-updateProxyWhenReconnect' method found
This warning is coming for the following line of code:
if(delegate) [delegate updateProxyWhenReconnect];
Can anybody help me to overcome these warnings?
A forward declaration is used when the header file will be imported after the interface. It looks to me that you've used the #class directive after the interface for the class itself.
The normal use of a forward class declaration looks like this:
#import "SomeSuperClass.h"
#class Forwardclass;
#interface SomeClass : SomeSuperClass
{
Forwardclass anIvar;
}
#property Forwardclass anIvar;
#end
#import "SomeClass.h"
#import "ForwardClass.h"
#implementation SomeClass
#synthesize anIvar;
-(void) setAnIvar:(ForwardClass *) aForwardClass;
#end
The #class directive is never used in an implementation (.m) file.
That's not what #class is for.
You use #class in the header file for another class, to tell the compiler that the class you're declaring does exist. Without it, the compiler would not know that that's a class name, and when you declare a variable as holding a pointer to an instance of that class, the compiler would think that you're just making up words. Using #class is called forward-declaring the class.
Your situation is different. You're in the implementation file for that class.
What the compiler needs from you now is the class's #interface. The warning is telling you that the compiler needs an #interface, but you haven't given it one (so, as far it knows, the #interface “may not exist”).
Normally, you would have written the #interface in a header file; how now to get it into the implementation file?
That's where the preprocessor comes in, with its #import directive. At the top of the implementation file (ClusteringController.m), import the header file:
#import "ClusteringController.h"
The preprocessor will replace this with the contents of that file, then hand the preprocessed code to the compiler, which will see the #interface there.