Access method in another interface of same class - ios

I'm stuck on this problem, please help me.
I have a ViewController with class name: FLViewController. In the .m file, I declare some other interfaces:
#interface FLViewController (InternalMethods)
- (void)updateButtonStates;
#end
#interface FLViewController (AVCaptureManagerDelegate) <AVCaptureManagerDelegate>
-(void)adMobProcess
#end
In the implementation of FLViewController, I call method adMobProcess of Interface FLViewController (AVCaptureManagerDelegate) but the compiler said that "No visible #interface for FLViewController declares selector adMobProcess"
I can move the method above into the implementation of FLViewCOntroller (currently it is placed in the category AVCaptureManagerDelegate) however, I want to know how to call the method in another category.

By declaring your categories inside the .m file (which limits their scope to that one file), you've effectively declared some private methods for FLViewController. If this is what you want, you don't need categories.
Categories in Objective-C are meant to be reused. So you want to declare your categories in a header file (or files), and include those headers in any .m file where you use them.

Finally I found the cause. I didn't declare method signature in the Category, just only the method implementation in the Category implementation block.I declared the method and it works.

Related

Is it possible to use extension methods which are added at implementation file rather than interface file in objective c?

This is header file/Interface file(className.h).
Here printSomething method is declared as an extension. And I'll call it later in main.m
extension.h
#import <Foundation/Foundation.h>
#interface extension_class : NSObject
#end
#interface extension_class () // This is the external method which is added using extension
- (void) printSomething;
#end
This is the Implementation file(className.m). Here printSomething method is defined.
extension.m
#import "extensions.h"
#implementation extension_class
- (void) printSomething
{
NSLog(#"I'm the method defined inside extension class but declared by using extensions");
}
#end
So far everything works fine. Now My question is simple why can't I access that printSomething method if I declare(until now declaration and definition was not done in same file) it in implementation file. As in the below code snippet? (Please compare and observe the changes among above two .h and .m files with below ones to get my point)
extension.h
#import <Foundation/Foundation.h>
#interface extension_class : NSObject
#end
extension.m
#import "extensions.h"
#interface extension_class () // This is the external method which is added using extension
- (void) printSomething;
#end
#implementation extension_class
- (void) printSomething
{
NSLog(#"I'm the method defined inside extension class but declared by using extensions");
}
#end
This is main method which is common in both cases.
main.m
#import "extensions.h"
int main()
{
#autoreleasepool
{
extension_class *object = [[extension_class alloc]init];
[object printSomething];
}
return 'O';
}
So what is point in having extensions in objective C if it doesn't allow us to add methods anywhere we like? or Is there any other method to achieve what I said above?
You're free to define extensions in the .m file. This is incredibly common. Those extensions won't generally be known to importers of the .h file, so they won't easily be callable from other files. That's a good thing. It lets us make "private" extensions, which is very useful and common.
They're not really private. Anything can call anything in ObjC. Outside callers just won't know about the method. But they can declare the method themselves as a category (note the text inside the parentheses) and call it:
OtherClass.m
#import "ExtensionClass.h"
#interface ExtensionClass (ThingsIKnowYouHave)
- (void) printSomething;
#end
...
[extensionClass printSomething];
Or they could of course just call it directly without declaring it (though this can cause ARC problems, so avoid this in modern ObjC):
[(id)extensionClass printSomething];
Or they could call it as a selector (again, this can cause ARC problems; so using the category is best):
[extensionClass performSelector: NSSelectorFromString(#"printSomething")];
There's really not much point to creating extensions in the header file (i.e. "public" extensions). If it's in the header file, you might as well just put it in the interface. The most common use of extensions (basically why they were invented), is so you can define methods inside the implementation file.
Extensions shouldn't be confused with categories, where there is text inside the parentheses. These were created to help organize large classes, and later were used for "informal protocols" before #optional was added. Extensions can add methods directly to the base class. Category interfaces just say "this method might exist." Extension interfaces are formal continuations of the primary interface (the compiler requires that they be implemented).
For more on categories and extensions, see Customizing Existing Classes in the Programming with Objective-C guide. See also Defining Classes in the same guide, which may clear up some confusion I believe you have about header files and interfaces.

Undeclared Methods vs Categories in Objective-C

Imagine I have define a class MyClass as follows:
The class interface file:
#import <Foundation/Foundation.h>
#interface MyClass : NSObject
#property (nonatomic) NSString *myProperty;
- (void)myPublicMethod;
#end
The class implementation file using categories:
#import "MyClass.h"
#interface MyClass (MyCategory)
- (void)myPrivateMethod;
#end
#implementation MyClass
- (void)myPublicMethod {
NSLog(#"myPublicMethod was called!");
[self myPrivateMethod];
}
- (void)myPrivateMethod {
NSLog(#"myPrivateMethod was called!");
}
#end
An alternative class implementation file NOT using categories:
#import "MyClass.h"
# implementation MyClass
- (void)myPublicMethod {
NSLog(#"myPublicMethod was called!");
[self myPrivateMethod];
}
- (void)myPrivateMethod {
NSLog(#"myPrivateMethod was called!");
}
#end
Was hoping someone could explain the difference between the two implementation file approaches.
Is it the case that using categories means the "private" methods are inherited by any subclasses of MyClass and not using categories means the "private" methods are not inherited by any subclasses?
All methods that exist on a class are always inherited and are callable by anyone regardless of how you declare them. The main difference is whether anybody knows about them. There was also a historic need to declare things before use which leads to internal forward declarations in older and old-style code.
A category is used to add methods to an existing class. A common use is to extend the functionality of one of the existing classes. For example you might implement:
#interface NSURL (HTTPQueryParameters)
- (NSDictionary *)httpQueryParameters;
#end
So from then on you've given NSURL itself the knowledge required to parse HTTP protocol query parameters. It's often the correct factoring to add functionality directly to classes you don't have the source for.
Objective-C used to follow the C rule that methods had knowledge only of those methods that had preceded them within the compilation unit. So to be able to call a method that appeared later in the source file you'd need a forward declaration. If you didn't want to publish that method for the world to see you could achieve that with a category or a class extension (which for this purpose is just an unnamed category).
Nowadays Objective-C methods can call any method that is defined anywhere within the compilation unit, including subsequently in the same source file. It's therefore now normal not to collect up your unpublished methods into a category or an extension just for the benefit of the compiler.
That leaves categories for:
adding functionality to existing classes; and
segmenting your classes if they become very large;
Class extensions are now primarily for:
declaring #propertys without publishing them.
In Objective-C any method call can be sent to any object — objects are dynamically typed. So there's a mapping table in memory at runtime for every class from method name to implementation. The lookup process is to see whether the method is implemented in the class dispatched to. If not then dispatch to the superclass. An exception will be raised if the runtime runs out of superclasses.
The declaration of the method in a category #interface only serves to expose the method to users of the class, including -- as you mentioned in your comment -- subclasses.
(It would be much more usual to use a class extension (sometimes called an "anonymous category") declare a method that you're defining in the main implementation block. Actually, I'm not 100% sure what the interaction is between your category declaration and the main block definition -- I wouldn't have been surprised if it didn't compile, but it does.)
Thus, the only difference between your two examples is that the declaration allows you to create a private header in a situation where you want your own subclasses to access this method, but have framework users who you want to restrict.

Difference between declaring instance variable in .h file and .m inside the #interface braces

If some one can brief on declaring instance variable inside .h file inside #interface braces and in .m file #interface braces. like this below
#interface ViewController : UIViewController { NSString *str ; }
#interface ViewController () { NSString *anotherStr ; }
Thx
There's even a third place where you can define instance variables: at the implementation statement:
#implementation ViewController { NSString *yetAnotherString; }
AFAIK, in the olden times you could only define the instance variables in the main interface. The other two places were added later. You can also mix them (as long as they have different names).
The advantage of defining the variables at #implementation and also the class extensions #interface ViewController () level (when done inside an .m file) is that you can hide implementation details from users of your API. In other words, if someone reads the .h file (s)he doesn't know about the variables. This makes the visible API cleaner and is also a concept called "information hiding" which is quite important in object oriented programming: don't expose too much implementation details so you can change the implementation without breaking code using the class.
Note that you can also define IBOutlet variables at all three levels and Interface Builder will detect and use them!
So when you're deciding where to define the variable you can simply ask yourself: Do other people need to see the variable when they see the .h file? IMHO this is only true when you need/want to make a variable #public. For all other cases, you can define them at the class extension or implementation level to make the API cleaner.
Whatever you declare in ViewControllerA.H is public. It means that other view controllers that contain the ViewControllerA object can access use the methods or variables directly. Whatever you declare in .M is private, other view controller can not access it immediately.
As for my own practice, most of the variable (I don't use much) or properties I declare in .M to prevent other view controller to access it directly. It is just like one concept in Object Oriented Programming - Data Encapsulation.
Note: Please be reminded that this should not be confused with #public, #protected, #private like DarkDust mentioned below. It will be another different topic.
In objective-C while you declare the member in .h file, it becomes visible to the other file when .h file is imported as header.
By default all member variables are private. So, user can not use them directly. But with methods of runtime.h and setValueForKey give them an alternate way to set those variable.
To avoid the user to do such mischief, its advisable to declare your private variables in .m file. They are called extensions as well.
For example you have created a variable in your appdelegate file. Now import appdelegate.h file to other .m file. Get the instance of appdelegate by sharedApplication delegate. Now you can set value by below way.
[appdelegate setValue:your_value forKey:#"name of variable"];
Though it was private, user could do so. Its because when you check for auto suggestion window, it will list down your private variable with strike through. To avoid getting those variable inside this window, it is advisable to declare them in .m file.

(Objective C) Do methods and variables need to be declared in head file(.h) if it is only used in its own class?

I have reviewed many code samples and have found that people commonly declare all methods and global variables in the header (.h) file. Is it necessary?
Methods to be used publicly (i.e. by classes other than the class implementing the method) and (truly) global variables should indeed be declared in the header file. The whole point is that you can import the header file in another source code file to gain access to the functionality declared there.
Methods that are meant to be private -- that is only to be called as part of the internal implementation of a class -- can be declared in a class extension. With recent versions of LLVM/Xcode, you actually don't even need to do that for non-#property methods. You can simply implement them and the compiler will be smart enough to see that they're there when called from other methods in the same class's implementation.
If you need to explicitly define a private ivar (rare these days), you can do so in a brace-enclosed section immediately after #implementation or #interface ClassName ().
In short: declare methods, functions, and variables that need be accessible from other classes in the .h file. Private methods and variable should be kept private by declaring them only in the .m file.
In recent versions of the SDK, you don’t have to declare methods that you only use internally to the class, so that can cut down clutter in your .h file. In general, the only methods, properties, and ivars that I put in my .h are the ones that I know other classes will need access to. That way, I never make the mistake of externally accessing a property that is supposed to be internal-only. The rest, I put in a class extension in the .m file like this:
#import "MyClass.h"
#interface MyClass ()
{
int _myIvar; // I rarely use these anymore,
// but if you want to use them, they go here.
}
#property (strong, nonatomic) NSArray *someArray;
#property (strong, nonatomic) NSDictionary *anotherProperty
#end
#implementation MyClass
#end
Header files have no special significance at all to the compiler. The preprocessor just copy-pastes them into the implementation file when you write #import anyway.

Declaring variables in .h file

Just wondering if its good programing practice to have a lot of variables declared in the .h file.
I'm writing my first app through which im learning xcode and obj-c. This ios app has just one xib, one .m and one .h file. I find my self a lot of times where i have a certain variable that i need to use in different methods/places in the .m file and i just end up declaring it in the .h file which seems like im making the variable global which i dont think is a good idea to have a lot of those.
Is this safe/ok to have a lot of variables declared in .h file or should i approach it in some other way?
Thanks
Is this safe/ok to have a lot of variables declared in .h file or
should i approach it in some other way?
It's absolutely OK to include a lot of variables in the .h! It just increases compile time a little and increases the size of your binary by an arbitrary amount. If it worries you, just split your implementation across a couple of categories.
I find my self a lot of times where i have a certain variable that i need to use in different methods/places in the .m file and i just
end up declaring it in the .h file which seems like im making the
variable global which i dont think is a good idea to have a lot of
those.
Variables that are accessed outside of one method should always be declared as iVars, and as properties if they require strong reference, or need to be accessed by outside classes. Global variables are way different, and you needn't worry about it.
Your .h file is the public interface of your class. It should only contain properties and methods that other classes need to know about.
You can declare ivars and internal methods and properties in a class continuation in the .m file (this is so common that one is now automatically included in the template for UIViewController subclasses).
You can also declare ivars within braces directly after the #implementation.
In iOS5, with ARC, declared ivars are strong references by default, so you don't have to use properties or accessor methods, but that choice depends on the rest of your class. For example, you may use lazy instantiation or perform other tasks or KVO when getting or setting a variable, in which case you'd always want to access it via a property or method, and if you're doing that for some ivars, and not others, it starts to look a bit messy.
It is alright for you to have many variables declared in the interface in the .h file when needed (as touched on by the other answers). But it would be wise for you to consider moving instance variables that do not need to be public into a category in the .m file. For example:
In the .h:
#import <Foundation/Foundation.h>
#interface SomeClass : NSObject {
NSDictionary *publicDict;
NSArray *privateArray;
}
#property (nonatomic, strong) NSDictionary *publicDict;
-(void)publicMethod:(id)anObj;
#end
And in the .m file:
#import "SomeClass.h"
#interface SomeClass () //Category that denotes private methods
#property (nonatomic, strong) NSArray *privateArray;
-(void)privateMethod;
#end
#implementation
#synthesize publicDict;
#synthesize privateArray;
-(id)init {
//...
}
-(void)publicMethod:(id)anObj {
//..
}
-(void)privateMethod {
//..
}
#end
This causes the compiler to issue a warning whenever any of the private methods contained in that category are accessed by outside classes. Additionally, this is the widely accepted way of adhering to an aspect of encapsulation in Objective-C.

Resources