How to pass value to a variable in an inherited class - iphone

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 = #"";

Related

Using class extensions in xcode 4.4

Since xcode 4.4 you don't need to #synthesize properties anymore (see here), the compiler does it for you. So, why does the compiler complain
use of the undeclared identifier _aVar
in my viewDidLoad method of ViewControllerSubclass:
#interface ViewController : UIViewController
#property (assign, nonatomic) int aVar;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.aVar = 5;
NSLog(#"Super value: %d", _aVar);
}
#end
#interface ViewControllerSubclass : ViewController
#end
#interface ViewControllerSubclass ()
#property (assign, nonatomic) int aVar;
#end
#implementation ViewControllerSubclass
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"Subclass value: %d", _aVar);
}
#end
If I move everything to the one file instead of 4 separate files for the respective interfaces and implementations, the compiler instead complains that _aVar is private. But _aVar should have been automatically synthesized in my ViewControllerSubclass.
Still keeping everything in 1 file, if I move the initial property declaration to a class extension:
#interface ViewController ()
#property (assign, nonatomic) int aVar;
#end
The build still fails saying that _aVar is private.
If I go back to the 4 file setup for the respective interfaces and implementations xcode builds without even a warning.
If I then run the code:
[[[ViewControllerSubclass alloc] init] view];
the log statements in the above examples print out the following:
Super value: 0
Subclass value: 5
It makes sense that NSLog(#"Super value: %d", _aVar); produced a result of 0 because this variable is supposed to be private to the superclass. But then, why does NSLog(#"Subclass value: %d", _aVar); produce a result of 5??
This is all very odd.
You are confusing several different issues, and I'm somewhat confused when you talk about jumping between files and you don't specify where your errors are happening.
Anyway, there is the issue of instance variable visibility. If you declare your iVars within the interface scope, they are, by default, protected.
#interface Foo : NSObject {
int protectedInt;
#private
int privateInt;
#public
int publicInt;
}
#end
When you synthesize iVars, the instance variables themselves are private, unless you explicitly specify them.
Methods will always fire on the most derived implementation.
Now, when you call this...
[[[ViewControllerSubclass alloc] init] view];
You will allocate a subclass, initialize, and cause the view to be loaded. This code will execute...
#implementation ViewControllerSubclass
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"Subclass value: %d", _aVar);
}
#end
The first thing it does is call the base class implementation...
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.aVar = 5;
NSLog(#"Super value: %d", _aVar);
}
#end
Of course, it calls super, but that part's not important here. The next line assigns 5 to self.iVar. But, which iVar? It calls the property setter method on this object. What type is this instance? It's a ViewControllerSubclass. Since you have given both your base class and its subclass the same name (and declared the property as part of the class extension), they each have their own private-scope instance variable .
However, a method is called on the most derived implementation. Thus, self.iVar will set the instance variable of the subclass. The instance variable for the base class remains unchanged.
When you NSLog the value, you are accessing the private instance variable of the base class, which has not been changed.
Now, after the base class viewDidLoad finishes, we get the code running for the subclass. It logs the value of its private instance variable, which was changed as a result of the base class calling the property setter. So, it will now print it's value, which is 5.
When you make the superclass declaration public, the compiler won't attempt to re-synthesize the property; it assumes that's been taken care of in the superclass. Thus, _aVar is not in scope anywhere in the subclass. It's private anyway, so even when you put them all in the same file that's why you see those errors.
However when you make the superclass property declaration inside the class extension, the compiler will auto-synthesize the property for both the superclass and the subclass. This ends up with both classes having private instance variables _aVar (with two distinct addresses). However, when the superclass viewDidLoad method sets the property, the method invokes the subclass's accessors, which set the value of the subclass's private _aVar variable, and not the superclass's. So that explains why you see the superclass value not changing.
Hope this helps!
I just tested your setup and could replicate your error. I came to the following conclusion:
You need to declare your #property in a .h file. If you want a private variable, declare it in .m in the category #interface (the one with the parentheses).

Unable to access object of other class

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

iphone - setting a property on another class

I have a property declared on a class:
.h
#interface myClass : UIView {
BOOL doStuff;
}
#property BOOL doStuff;
.m
#synthesize doStuff;
this class is a delegate of another one. On the other class, I am trying to set this property, doing something like
[delegate setDoStuff:YES];
I receive an error telling me that "method -setDoStuff: not found..."
How do I declare the property on the class, so other classes can read and set them?
thanks.
is your delegate declared as type "id" ?
either you declare its true type MyClass delegate in the other class (which points to your myclass) or
declare a protocol that delegate has to implement id in declaration.
Last (but not right approach) is to typecast it [(MyClass)delegate doStuff].
Make sure that you’re importing your custom class’s header and that delegate is declared as an instance of that class.
you could also specify the name of setter function in #property.
#property (nonatomic,setter = setMyDoStuff,assign) BOOL doStuff;

Objective-C private instance variables definition

Is there any difference in where we define private instance variables? As I understand there are two possibilties:
1) In header file
#interface MyViewController : UIViewController {
#private
NSString *fooString;
}
2) Second way is to define it in the implementation:
#implementation MyViewController
NSString *fooString;
What is the difference? Cheers!
In 2nd case fooString is not instance variable - it is global variable, so your two cases are completely different
The first way defines a private instance variable. Each object of class MyViewController will have its own private fooString.
The second way defines a global variable. There will be only one instance of fooString and it will be visible to any source file with the following declaration:
extern NSString *fooString;
The first one is a unique fooString per MyViewController that you create.
The second is a fooString that every MyViewController shares.

cocoa - referencing a method on the parent

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 ...].