Calling a method with return type "void" in same file - iphone

I've got a simple question.
In Objective-C, when you have a method you want to call, with a return type of void, how you you call it from another method?
The way I've been doing it in my application is this:
[self nameOfMethod];
But that causes Xcode to spit out the following error:
Method '-nameOfMethod' not found (return type defaults to 'id')
Though it seems to still be executing.
Am I calling it right, or is there a better way?
Thanks!

I’m guessing you haven’t declared -nameOfMethod in the class interface and you’re calling it from another method whose implementation precedes the implementation of -nameOfMethod, i.e.:
- (void)someMethod {
[self nameOfMethod];
}
- (void)nameOfMethod {
// …
}
When the compiler is parsing -someMethod and -nameOfMethod hasn’t been declared in the class interface, it generates a warning because it doesn’t know about -nameOfMethod yet.
There are essentially two solutions for this. You could reorder the implementation file so that -nameOfMethod appears before -someMethod, but that’s not always possible. A better solution is to declare -nameOfMethod in the class interface. If -nameOfMethod is supposed to be called by clients of your class, place it in the corresponding header file. On the other hand, if -nameOfMethod is only supposed to be called inside your implementation file, use a class extension. Supposing your class is named SomeClass, this is what your header and implementation files would look like:
// SomeClass.h
#interface SomeClass : NSObject {
// … instance variables
}
// … external methods
- (void)someMethod;
#end
// SomeClass.m
#import "SomeClass.h"
#interface SomeClass () // this is a class extension
// … internal methods
- (void)nameOfMethod;
#end
#implementation SomeClass
- (void)someMethod {
[self nameOfMethod];
}
- (void)nameOfMethod {
// …
}
#end
Using class extensions, the order of method implementations won’t matter.

You need to make sure that your interface file contains a definition for nameOfMethod - so;
-(void) nameOfMethod;

You're calling it correctly, but make sure that the interface for your (void) method is in your .h file.

Related

How to create global protocol method in iPhone?

I create one protocol method and I want to implement the protocol method in multiple classes
#protocol XMLProtocol <NSObject>
- (BOOL) hasAllRequiredAttributes :(NSDictionary*)attributeMap;
#end
I have use this following class methods
#import "XMLProtocol.h"
#interface MachineA : NSObject<XMLProtocol>
and its implementation method I will implement the protocol method
- (BOOL) hasAllRequiredAttributes:(NSDictionary *)attributeMap {
return false;
}
and also i use this protocol method in another class
#import "XMLProtocol.h"
#interface MachineB : NSObject<XMLProtocol>
and its implementation method I will implement the protocol method
- (BOOL) hasAllRequiredAttributes:(NSDictionary *)attributeMap {
return false;
}
my thought is where should I call the protocol method. I totally confused. How can i do this.
One way you can define a global implementation for your protocol method (if I understand correctly what you are asking) is defining a category on NSObject:
#implementation NSObject (XMLProtocol)
- (BOOL) hasAllRequiredAttributes:(NSDictionary *)attributeMap {
return false;
}
By doing like this every object will have that method. Don't know if this is sensible, but it's a way.
Another way would be defining a Machine base class from which both MachineA and MachineB derive; the protocol method would be defined in the base class:
#interface Machine : NSObject <XMLProtocol>
...
#implementation Machine
- (BOOL) hasAllRequiredAttributes:(NSDictionary *)attributeMap {
return false;
}
....
#end
#interface MachineA : Machine
...
and any derived class could redefine it, if required.
This is not as "global" as the NSObject category, but it might be a better solution if you can define a base class for all the classes that need implement that protocol.
You must write the implementation of the method in both classes, even if the implementations are identical.
In you particular situation notification would be great help full to you. Notification works same like protocol except it broadcast the message. so you could receive that call on multiple classes.
if you want to done with protocol than also it is very easy. just make sure you current view controller is referenced with delegate (i.e. obj.delegate = self). you can implement that on -viewWillAppear. so your current view controller only get called of that method. Delegate will only call one method at one place in a time.
IMHO a global protocol is not very good design for something as specific as XML parsing.
A #protocol doesn't have any implementation part by itself. It is just an API definition, think of it like a contract. Any class that conforms to a protocol must implement its mandatory methods and properties (there is a #optional clause).
For instance, you may have two implementations of an XML parser, one that works in iOS 4 and another one that works in iOS 5+. Both declared as conforming to XMLProtocol protocol. And both implementing - (BOOL) hasAllRequiredAttributes :(NSDictionary*)attributeMap;, let's imagine that they need to implement it differently.
Thanks to being compliant to XMLProtocol you don't care about the implementation details. You know that you'll pass an attribute map and you'll obtain a boolean indicating if it has all required attributes.
You call the method where ever you use those classes:
id <XMLProcotol> parser;
if (iOS4) {
parser = [[OldXMLParser alloc] initWithString:<#...#>];
} else {
parser = [[NewXMLParser alloc] initWithString:<#...#>];
}
/* you call the method without caring which parser class
* has been actually created thanks to the protocol
*/
if ([parser hasAllRequiredAttributes:theMap]) {
...
}
If the implementation of the methods are identical, you can make both a subclass of a common parent class that implements the common methods, present or not in the protocol.

Implementing run time polymorphism and inheritence

What is the equivalent concept of interface in java in objective C. I want to create a interface and define some common variables and methods which will be shared by many classes inheriting from my interface. When any class outside want to use a child class it will get a reference object of my interface which will point to correct child class.
How to achieve this in Objective C?
An Objective C equivalent of Java interfaces is called "protocol".
A small intro can also be found here, and if you want a full reference, it's at Apple
In Objective-C, you can achieve this by making use of Protocols. A protocol is basically the precursor to an interface in Java, so most of the behavior should come naturally.
A protocol declaration looks like the following:
#protocol Foo
-(void) foo;
-(int) boo: (int) arg;
#end
It may be implemented by a class. In the following case, you would say MyClass conforms to the Foo protocol.
#interface MyClass <Foo>
{
}
#end
#implementation MyClass
-(void) foo {
//do something
}
-(int) boo: (int) arg {
//do something else
return arg;
}
#end
Finally, you can pass them around like this:
-(void) someMethod: (id<Foo>) arg;
If you need to be more specific about the object, they can also be used like this:
-(void) someMethod: (NSObject<Foo> *) arg;

How to call a method without an instantiated object

This is an objective-c question.
I would like to call a method in an object, but there is no instantiation of the object. Is this possible?
The method I want to call is not a class method.
You can't call a method on an object that doesn't exist. But you can call a method on a class even if you have no instantiated objects of that class. (That's what alloc is in #fbrereton's answer -- a class method).
Class methods are declared and defined with a + instead of a -, are called on the class rather than the instance, and cannot access self or any instance variables in the class (for reasons that should be obvious).
Unless the method is static you will not be able to do this. static routines in Objective-C will be prepended with a +. For example NSObject provides these two routines (among many):
+ (id)alloc; // static - an NSObject instance is not required
- (NSString*)description; // nonstatic - an NSObject instance is required
One would make the respective calls like so:
NSObject* result = [NSObject alloc];
NSString* desc = [result description];
Sorry to nit-pick Chris' terminology, but we don't call a method on an object in Objective-C, we send a message to an object. When you send a message, the runtime will look up the appropriate method and call it. The distinction matters.
Perhaps you just want a plain-old C function. If you don't want a class method, and you don't want an instance method, that appears to be your only option. Don't be afraid of using C functions in Objective-C. Every technique has its place.
You can indeed invoke an instance method without an instance, provided it is functionally a class method (that is, it accesses no instance variables). Here's an example:
/*
Compile with:
gcc -framework Foundation inst_method_without_inst.m -o inst_method_without_inst
*/
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#interface Foo : NSObject {
}
- (BOOL)doSomethingWithThis:(NSString *)this;
#end
#implementation Foo
- (BOOL)doSomethingWithThis:(NSString *)this {
NSLog(#"Look, it's this: %#", this);
return YES;
}
#end
typedef BOOL (*my_sel_t)(id, SEL, NSString *);
int
main(void) {
Class cls = [Foo class];
SEL my_sel = #selector(doSomethingWithThis:);
Method m = class_getInstanceMethod(cls, my_sel);
// You could also use +[NSObject instanceMethodForSelector:] to get |m|,
// since |cls| is a kind of NSObject.
my_sel_t f = (my_sel_t)method_getImplementation(m);
BOOL result = f(nil, my_sel, #"Hello from an instanceless instance method invocation!");
NSLog(#"result: %d", (int)result);
return EXIT_SUCCESS;
}
You could get it to work even if the instance method accesses instance variables by allocating memory for it to work with (using either +alloc or class_getInstanceSize() plus malloc()) and passing a pointer to that memory as the first id argument to the implementation instead of nil.
While this is entertaining as an exercise, I can't think of a good reason to not just instantiate the class and use the standard messaging syntax and compiler support. In fact, the only reason we couldn't just do [(Foo *)nil doSomethingWithThis:#"BOO!"] here is that objc_msgSend() special-cases messages to nil with the result that NO is returned and nothing happens.

Public scope in Objective-C?

I’m sure this is a simple one, but it’s been elusive so far, and I’m stumped ...
How do I declare an Ivar so that it’s accessible from ALL Classes in a project?
[Don’t know if it matters, but the ivar in question is (an instance of) my Model class, whose data needs to be accessible to various view controllers.]
Best as I can tell from "The Scope of Instance Variables” in The Objective-C 2.0 Programming Language
... this would be by using the “#public” directive.
So I’ve tried this in the #interface block where the ivar is declared:
#interface ...
...
#public
ModelClass *theModel;
#end
... But when I try to refer to “theModel” in a different class, the compiler doesn’t auto-complete, and when I type it in anyway, the compiler shows:
“Error: ‘theModel’ undeclared (first use in this function)”.
I assume this is a question of Scope, and that I haven’t made the ivar available appropriately, but how? Somehow I need to access this, or make its pointer available somehow.
Any ideas would be VERY much appreciated. Many thanks!
Perhaps you forgot to put the instance variable inside the braces of the class where all instance variable declarations go?
#interface Foo : NSObject {
// other instance variable declarations
#public
ModelClass *theModel;
}
// method and property declarations
#end
Also, can you show us the code of how you are trying to access the instance variable from elsewhere? The proper syntax should be:
myFooInstance->theModel
where myFooInstance is a value of type "Foo *"
I make properties available to all views managed by a Tab Bar via a singleton representing my data model. This is efficient and allows all Views access to the data (as well as any other application elements. Creating the singleton is straightforward (there are a ton of examples on S.O.). The you just request the instance and get the property values you need.
Here is a framework fro creating the Singleton. The key points are the static instance and the fact that you do the initialization as [[self alloc] init];. This will ensure the object gets cleaned up correctly. All the methods at the bottom of the class are standard from the SDK Docs to make sure release calls are ignored (because the object is shared globally).
Singleton Boilerplate (ApplicationSettings.m):
static ApplicationSettings *sharedApplicationSettings = nil;
+ (ApplicationSettings*) getSharedApplicationSettings
{
#synchronized(self) {
if (sharedApplicationSettings == nil) {
[[self alloc] init]; // assignment not done here
}
}
return sharedApplicationSettings;
}
+ (id)allocWithZone:(NSZone *)zone
{
#synchronized(self) {
if (sharedApplicationSettings == nil) {
sharedApplicationSettings = [super allocWithZone:zone];
return sharedApplicationSettings; // assignment and return on first allocation
}
}
return nil; //on subsequent allocation attempts return nil
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (unsigned)retainCount
{
return UINT_MAX; //denotes an object that cannot be released
}
- (void)release
{
//do nothing
}
- (id)autorelease
{
return self;
}
You cannot access iVars from any other class.
You have to declare a getter/setter method to change or view a variable from another class - what you are really looking for are properties, that make it easier to define and access these getter/setter methods.
In your example above, you'd have the property defined just after the block that defines the local variable in the header file:
#property (nonatomic, retain) ModelClass *theModel;
In the implementation file you'd have the getter/setter created with the #synthesize statement just after the #implementation line:
#synthesize theModel;
Then if you have an instance of your class created, you access the class instance variable like so:
myInstance.theModel = [[[ModelClass alloc] init] autorelease];
The reason #public & #private are in there are to define visibility for subclasses (which, being extensions of that class type also get all the class local variables defined by a superclass), not for any random class.
The standard Objective-C way of doing it is to have a class method that returns the ivar
In your .h file:
+ (id)defaultModel;
and in your .m file:
static ModelClass * defaultModelInstance;
#implementation ModelClass
+ (id)defaultModel {
if (!defaultModelInstance) {
defaultModelInstance = [[ModelClass alloc] init];
}
return defaultModelInstance;
}
#end
although this will need tweaking if you need a specific ivar instead of just "a ivar that's always the same"
this type of design is used by many Cocoa classes i.e. [NSWorkspace sharedWorkspace]
Think a C global variable.
Adding:
extern ModelClass* theModel;
after the #end in the header will make the variable visible anywhere you include the header.
In the ModelClass.cpp file add:
ModelClass* theModel;
before the class implementation.
The variable will still have a value of nil until you allocate and initialize it though and you will be resposible for ensuring that it gets deallocated at the correct time.
THANK YOU ALL for the very helpful discussion on this topic! Clearly there are several ways to approach things here, so this is a very useful assortment of techniques.
Just to let y'all know that in researching this issue further, I ran across a couple of other very helpful pages, listed below. They include mention of the NSNotificationCenter, which I hadn't heard of before; as well as the idea of the "dependency injection" design pattern.
The idea is to keep "low coupling"(1) between the classes, making the code more modular & better for unit testing.
And while the 'notification' pattern sounds like a great idea, in this case it may be a bit overkill, considering that I only need ONE instance of the data model throughout the run of the app, and it doesn't change throughout.
Finally, even though the "#public" compiler directive is well-documented in Apple's Obj-C guide(2), I later found a fascinating edict in a different doc stating that it shouldn't be used! Quoted from Apple's own Cocoa Fundamentals(3):
"Give the proper scope to your instance variables. Never scope a variable as #public as this violates the principle of encapsulation. ..."
(Strange that they don't mention this in their 'Objective-C 2.0' guide where the directive is actually explained.)
Anyway, here are a couple of other links I found to be full of some great insights as well. FYI:
S.O.: "What’s the best way to
communicate between
viewcontrollers?"(4) <<
CocoaWithLove: "Five approaches to
listening, observing and notifying in
Cocoa"(5)
CocoaWithLove: "Singletons,
AppDelegates and top-level data"(6)
Hope these help. Anyway, thank you all again!
Best,
rond
P.S. Yikes! It won't let me post more than one inline hyperlink, so I'm listing them here instead. Obviously, they’re all prefixed by “http://” ... :O
(1): en.wikipedia.org/wiki/Coupling_(computer_science)
(2): developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/ObjectiveC/Articles/ocDefiningClasses.html#//apple%5Fref/doc/uid/TP30001163-CH12-TPXREF127
(3): developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/AddingBehaviortoaCocoaProgram/AddingBehaviorCocoa.html#//apple_ref/doc/uid/TP40002974-CH5-SW12
(4): stackoverflow.com/questions/569940/whats-the-best-way-to-communicate-between-viewcontrollers
(5): cocoawithlove.com/2008/06/five-approaches-to-listening-observing.html
(6): cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html

Assigning a protocol to an NSMutableDIctionary?

I am using a singleton backbone in my application to handle accuring errors. They will be handled inside the singleton and broadcast a notification throughout the app when the error has been fixed. Anyways this is not what my question is about but when I pass a new error to the singleton object like this
[[SingletonErrors sharederrors] addError:ErrorDictionary_here];
I want ErrorDictionary_here to be a NSMutableDictionary protected by a given #protocol in my code so whenever I give my code to others in my team they get warnings about error information they might have forgotten to pass into the dictionary.
Is this even possible for starters because this is about adding protocols to setters and a getter is much more easy like
-(NSMutableArray< myprotocol > *)getmyError{
}
I hope some one can help me out.
I'm not seeking for passing objects (read class instances) instead of the dictionary just a protocol applied on my dictionary.
It is also possible to implement a protocol through a category like so:
#interface NSMutableDictionary_TD(ErrorExtensions) <ErrorProtocol>
#end
#implementation NSMutableDictionary(ErrorExtensions)
//implement the ErrorProtocol here
#end
If I understand what you're asking, you should be able to do this without too much hassle. In your singleton class SingletonErrors, you should have:
#interface SingletonErrors : NSObject {
// some definitions ...
// The current array of all errors. This can also be an NSMutableSet if you like
NSMutableArray *sharedErrors;
// more definitions ...
}
// some properties ...
#property(nonatomic,retain) NSMutableDictionary<ErrorProtocol> *sharedErrors;
// more properties ...
- (void)addError:(NSMutableDictionary<ErrorProtocol> *)newError;
#end
You should create the protocol to be implemented. In this sample protocol, let's say you want to provide a single method to check whether the object is valid - that is, the dictionary contains all the relevant information.
#protocol ErrorProtocol
- (BOOL)isValid;
#end
You'll then need to subclass NSMutableDictionary so that your class implements the ErrorProtocol protocol:
#interface MyMutableDictionary : NSMutableDictionary <ErrorProtocol> {
}
#end
#implementation MyMutableDictionary
- (BOOL)isValid {
// Do your validity checking here
return YES; // Obviously change this line
}
#end
Then, whenever you throw an error, you can pass in a new instance of MyMutableDictionary to SingletonErrors, and have it call the isValid selector on the MyMutableDictionary, since it's assured that the dictionary will conform to ErrorProtocol and responds to isValid:
- (void)addError:(NSMutableDictionary<ErrorProtocol> *)newError {
if([newError isValid]) {
// Add the new error to the current array of errors
[self.sharedErrors addObject:newError];
// Other code to "broadcast" the error would go here
} else {
// Some code to error out of adding the error would go here
}
}
Overall, what this solution does is:
Hold a NSMutableArray of all errors in SingletonErrors
Each error is an NSMutableDictionary that conforms to ErrorProtocol
The object we use for each error is MyMutableDictionary, a subclass of NSMutableDictionary
The protocol ErrorProtocol defines a method isValid that checks whether the error is OK to be added
The SingletonErrors object calls the isValid method and adds the error appropriately
Thats correct but the doesnt feel nice to me .. my solution merged with tim`s was
#implementation NSMutableArray (myAddition)
- (BOOL)isValid {
// Do your validity checking here
return YES; // Obviously change this line
}
#end
This saves a load of code .. Im a Objective C in blood and fains .. less is better :) .. thanks for your reply anyways because im sure this issue is not a basic objc issue. Its more advanced and i think loads of people will find this topic and see the fix and you fix is 100% right as well so thanks for that !..
My heart is to small to store the loving replies i get here :).