I had a method on my main view controller named "calculateThis".
This method was run, obviously, as
int newValue = [self calculateThis:myVariable];
when I run it from inside the view controller.
Then I created a static class and I need to run this method from there.
How do I reference this method from that class using just relative references, as super, superview, delegate, etc. I cannot use the class name defined on the delegate because this static class is used in several apps of mine.
I need to go up in the hierarchy, I imagine one level, and access the method there...
thanks.
Define your utility methods in a category on NSObject or related subclasses of NSObject.
Which you have done.
Adding (id)sender to your method will work. Then your method can reference the object that called it. Something like this.
+(int)calculateThis:(id)sender userInfo:(id)info;
then your call becomes.
int newValue = [NSObject calculateThis:self userInfo:myVariable];
If your intent is to create a class that you can use without initializing it, that's possible using class methods. For instance, if I want to make a class called MyClass with a doSomethingWith: method, I would define the following:
In MyClass.h:
#interface MyClass : NSObject {
}
+(void)doSomethingWith:(id)thisObject;
#end
In MyClass.m:
#import "MyClass.h"
#implementation MyClass
+(void)doSomethingWith:(id)thisObject
{
// Your code goes here.
}
#end
To reference this method in another class, you can use the class object for MyClass like so:
[MyClass doSomethingWith:#"Hello, World!"];
This isn't really a typical Cocoa or Cocoa Touch design pattern, but can be handy for things like calculations.
Are you talking about the superclass? If so, you use [super ...].
Related
I have a class called TimeLineViewController which is inherited from MyViewController. I need to pass a value to a variable from MyViewController to TimeLineViewController. How can i do it ?
MyViewController.h
#interface MyViewController : TimeLineViewController {
.....
}
In TimeLineViewController.h i have a String *str assigned. From MyViewController.m i need to pass a value to the String *str variable in the TimeLineViewController class. How can i do this.
I tried the following from MyViewController.m but none worked.
[super str]=#"hi";
The point of inheritance is using existing functionality and extending it for specific needs by the sub class(es)
So... If your TimeLineViewController inherits from MyViewController there is no need to declare the member again in TimeLineViewController and you can just use it with since it was already declared for MyViewController:
self.str = #"hi";
If str is a property inside the class TimeLineViewController you can access it via inheritance in MyViewController. So if you change it in MyViewController it changes also for the father.
Remember:
A
|
B
if in A you have a property c then you can do B.c.
Read this.
From the apple's doc,
The instance variable is accessible within the class that declares it
and within classes that inherit it. All instance variables without an
explicit scope directive have #protected scope.
So you can just use as
super.str = #"hi";
You should have setter or property in TimeLineViewController.
Then you can use
[self setStr:#""];
or
self.str = #"";
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Objective C — narrow instance variable types in subclasses?
I have a class called ParentClass which has a UIView property. I also have a class called ChildClass which is a subclass of ParentClass. ChildClass obviously inherits the UIView property, but in ChildClass I know for certain I'll only be using a UIScrollView for this property.
My question is, is it possible / feasible to somehow "subclass" the UIView property, rename it, and make it so it can only be a UIScrollView? Would I have to override the property in the .m file when I synthesize?
Similar to how a UITableViewController's main view property is a UITableView rather than a UIView as in UIViewController.
UPDATE: Maybe I just didn't mean property, but also the variable itself.
Just add a property with the same name to your child class but with UIScrollView instead of UIView.
If you're subclassing ParentClass, that has a property of a UIView and you need ChildClass to inherit a UIScrollView.. You should just make a UIScrollView property in ParentClass so ChildClass can inherit and use it.
If ChildClass isn't going to use the UIView property, if you never initialize it will remain nil therefor not using up any of your memory. Also giving you the benefit, if and or when you choose to use the UIView property you can.
Alternatively, simply declare a new UIScrollView property in ChildClass if you don't want to in ParentClass
Hope this made sense, and helps !
Properties are converted into methods, and these methods can be overridden just like any other. You can do something like this:
#interface ParentClass {
NSView* myView;
}
#property(retain) NSView* myView;
#end
#implementation ParentClass
#synthesize myView;
#end
#interface ChildClass
#end
#implementation ChildClass
-(void) setMyView:(NSView*)v;
{
if([v isKindOfClass:[UIScrollView class]]){
[super setMyView:v];
} else {
//do whatever error handling you want to here
}
}
#end
The -setMyView: method is one of the methods that the property was converted into, so defining it in ChildClass will override the one on the parent class.
Side note: when you refer to "subclassing" the property, the correct term is "overriding."
I am accessing object of one class in the another class. But instance variable is Showing null.
This is my code.
fvcObj = [[FirstViewController alloc]init];
NSLog(#"%#",fvcObj.user);
Which things to take care in declaring object of another class?
Thanks.
As PengOne has said it is a new instance of the class FirstViewController and it cannot hold the data which you have assinged to the "user" variable in FirstViewController class. I think you want to pass data from one view controller class to other. If so then declare a method in the class to which you want to send the data and call this method from the other class and pass the data as a parameter of the method.
Hope this might help u.
Happy coding
fvcObj
is a new instance of FirstViewController, so my guess is that the user property has yet to be defined.
In header file (*.h) for example:
#interface MyClass : NSObject
{
NSString *someString;
}
#end
#property (nonatomic,retain) someString;
In implementation file (*.m)
#synthesize someString
This create setter and getter for someString
At the moment, the majority of my code is in the same viewcontroller, and i'd like to move some of it over to other areas. Such as moving the animations all over to somewhere else. But then how do i reference things which are in another class? And how do i reference back from that class to items in my viewcontroller class? Not going this has always disuaded me from doing it.
there is a couple of ways you can achieve that.
one way is the cocoa delegate #protocol way, the second way could be creating references to each object in the other class.
for the first way you can do something like this:
#class Class2;
#interface Class1 : NSObject {
Class2 *cls2Pointer;
}
#property Class2 *cls2Pointer;
#end
#class Class1;
#interface Class2 : NSObject {
Class1 *cls1Pointer;
}
#property Class1 *cls1Pointer;
#end
int main(){
Class1 cls1Obj = [[Class1 alloc] init];
Class2 cls2Obj = [[Class2 alloc] init];
[cls1Obj setCls2Pointer:cls2Obj];
[cls2Obj setCls1Pointer:cls1Obj];
}
the second way, is to declare a protocol in one/both of the classes to be able to pass arguments and call different methods on other objects:
#protocol Class1Delegate
- (void)class1:(Class1)obj MethodWithArg:(id)arg;
#end
#interface Class1 : NSObject {
id <Class1Delegate> delegate;
}
#end
#interface Class2 : NSObject <Class1Delegate>{
}
#end
#implementation Class2
- (void)class1:(Class1)obj MethodWithArg:(id)arg {
//do stuff when called from the 1st class
}
#end
You might like to look into this here - to create static classes in objective c and then reference them in a separate file by classname - as in the view controller quoted in the linked example.
Otherwise you can just create a new class within a separate .m file and then code it such that the calling method in another class will first create an instance of this new class and then invoke the necessary method on this instance.
Hope this helps.
Basically what you do is that you create one or more classes, move the code over to these classes and then create instances of these classes in your viewcontroller.
so if you had a method in your view controller
-(void)foo;
you would create a new class say C and move the method there.
then in your view controller you would create an instance variable of that class e.g.
C* myC;
then alloc/init and then call the foo method. This is not object oriented in the sense that foo is not really related to C in any way so method foo could have just been a static method not relating to the instance and as such called just like any other method but as [C foo] instead of [self foo] from the view controller.
the other more OOP method would be to move functionality that belongs to together into a separate class like animation in your example.
Looked for an answer for this question, but I haven't found a suitable one yet. I'm hoping you guys (and gals) can help me out! (This is for an iPhone app)
Alright, I have a Mutliview application. Each view has it's own class, and everything is happy. However, the different classes sometimes call the same method. Up until now, I have simply wrote that Method twice, in both of the class files.
This is what I want to do though:
I want to make a new class, in It's own file, that has all the "Common" Methods. Then, whenever another class needs to call the Method, I simply call it from the other file. This way, when I want to change the Method, I only need to change it in one place, and not all the places...
I'm not sure how I'd do this, which is why I'm asking for help. I'm a little rusty and new for Objective-C, so pretty examples will help me a lot. Allow me to give you one.
File: ViewController1.m
#implementation ViewController1
//Do Some awesome stuff....
CALL "CommonMethod" HERE
#end
File: ViewController2.m
#implementation ViewController2
//Do Some awesome stuff....
CALL "CommonMethod" HERE
#end
File: CommonClass
#implementation commonClass
- (void)CommonMethod:(id)sender
{
//So some awesome generic stuff...
}
#end
I feel like I need to #import the other file, make an Object from the class and call the Method from the Object... How do I do that?
Thanks again!
Option 1:
#implementation commonClass
+ (void)CommonMethod:(id)sender /* note the + sign */
{
//So some awesome generic stuff...
}
#end
#implementation ViewController2
- (void)do_something... {
[commonClass CommonMethod];
}
#end
Option 2:
#implementation commonClass
- (void)CommonMethod:(id)sender
{
//So some awesome generic stuff...
}
#end
#implementation ViewController2
- (void)do_something... {
commonClass *c=[[commonClass alloc] init];
[c CommonMethod];
[c release];
}
#end
Option 3: use inheritance (see Mr. Totland's description in this thread)
#implementation commonClass
- (void)CommonMethod:(id)sender
{
//So some awesome generic stuff...
}
#end
/* in your .h file */
#interface ViewController2: commonClass
#end
naturally you always need to #import commonClass.h in your view controllers..
There are some answers here telling you to create a common "parent" class. However I think that you can do a lot better. Create a category for UIViewController instead. You don't know all of the internals of what is going on with UIViewController so I don't think it is worth creating your own View Controller hierarchy off of. In fact it could be dangerous. I ran into a number of problems when I tried to create a "base" UITableViewController and then create classes that inherit from that. I avoided these problems by using categories instead.
Your #1 priority shouldn't be inheriting things for no good reason, it should be getting an app into the app store that people will want to download.
It sounds to me like the common code doesn't need to be in a class at all. Is there a reason you can't just use a C-style function for what you want to do?
You could put the common code in a class and then make your other two classes subclasses of that one; this method also avoids the code duplication.
Another option might be to write a class method instead of instance methods for this common code. I think most people feel that singletons are best avoided as a design choice.
It would be easier to give a good answer if we knew more about what you were really trying to accomplish.
What you want to do is to make the two controllers share a common superclass:
UIViewController : MyAwesomeViewController : ViewController1
: ViewController2
commonMethod: would then reside in MyAwesomeViewController. Also, don't start method names with capital letters. :)
To elaborate:
+#interface MyAwesomeController : UIViewController {
-#interface ViewController1 : UIViewController { // and ditto for ViewController2
+#interface ViewController1 : MyAwesomeController {
Bear in mind that Objective-C is just a superset of C, and that whilst #include directives are mostly used for header files, there's nothing stopping you using a #include to embed the contents of one implementation inside another implementation. If the code is truly identical, you can easily just stick it in its own file, and #include it in the .m file.
Having said that, perhaps it would be better to use this technique in conjunction with categories, especially if the same implementation has similar behaviours.
Pass in a reference to your commonClass when you alloc and init your views...
CommonClass *cc = [[CommonClass alloc] init];
ViewController1 *vc1 = [[ViewController1 alloc] ... initWith:cc];
ViewController2 *vc2 = [[ViewController2 alloc] ... initWith:cc];
but making a classic c include might suffice.
As an iPhone neophyte with a Java background and little C, I had a similar problem wishing to refer to a method in both the RootController and a ViewController. It seemed to me that the proper place for the method was the AppDelegate class, an instance of which one obtains in other classes by:
MyAppDelegate *delegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
then if the method is "doSomething" one accesses it by:
[delegate doSomething];
But perhaps this is too obvious or not what was required.
Another method that you can use
#interface ServerManager : NSObject
+(ServerManager *)getInstance;
#implementation ServerManager
+(ServerManager *)getInstance
{
static ServerManager *objServerManager = nil;
if(objServerManager==NULL){
objServerManager=[[self alloc] init];
}
// Return the servermanager object.
return objServerManager;
}
Call Whether you want to use
ServerManager *SMObject = [ServerManager getInstance];
Don't forget to import servermanager.h file.