iphone - setting a property on another class - iphone

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;

Related

How to pass value to a variable in an inherited class

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

Can we have retain property with no getter and setters on Obj C elements?

Ok, so I was reading some articles regarding Good Programming Practices and I came across a statement which said that making all your Elements public for your classes isn't a good idea.. aka The concept of Encapsulation.
Now in Objective C, When I create a element for my class, I do the following, consider an NSMutableArray
#property (nonatomic, retain) NSMutableArray* myArray;
WHY I DO THIS?
So as to give the Retain property to myArray and therefore, giving it a simpler Memory Management cycle. Later on, I initialize the myArray in viewDidLoad as
self.myArray = [NSMutableArray arrayWithCapacity:0];
Later in Dealloc...
self.myArray = nil;
WHAT ELSE HAPPENS
By giving this property and synthesizing myArray in .m file, what I am unknowingly doing is making Public Getters and Setters for all the elements of my class.
Also, the auto-generated UI Elements from Xib files, do have the same declarations applied.
That isn't a nice idea to keep creating public Getters and setters for each and every element of your class, right?
So, there's absolutely no kind of encapsulation applied! Please correct me if I am wrong here and help me with any solutions!
Thanks!
Simply use the principle of Class Extensions that allows you to put part of your declarations in your .m file, thus making it invisible in your header and invisible from other classes.
(This is Apple's recommended way to declare private methods and properties, by the way)
YourClass.h
#interface MyClass : MySuperclass
// public properties
// public methods
#end
YourClass.m
#interface MyClass()
// This is a class extension
// put here private properties
// and private methods too
#end
#implementation MyClass
// And your implementation of course here
#end
You can even declare a property as readonly in your public interface (in the header file) and redeclare it as readwrite in your private interface (in the class extension in the .m file) for example.
See the Apple documentation for more details.
Note that:
There is NO NEED to declare the instance variable if you declare the property: the compiler will generate it automatically for you so you don't have to bother and to declare it in the .h. In the latest version of the compiler (Modern Objective-C) there is even no need for the #synthesize directive as it now generate it automatically if not present (see doc)
If you prefer to declare instance variables anyway, you can also do this in the class extension in your .m the same way you would do in your .h. That's a way to hide instance variables from the public header too. In general I really rarely use instance variables (as declaring only the properties is sufficient) and if I really need an ivar I declare it in the class extension to make it not visibile in the public header.
You can declare the property in your class.m file, so the getter and setter methods are accessible only in that class. An example:
MyClass.h
#interface MyClass : NSObject {
NSMutableArray *_myArray;
}
#end
MyClass.m
#interface MyClass ()
#property(nonatomic, retain) NSMutableArray *myArray;
#end
#implementation MyClass
[... MyClass implementation ..]
#synthesize myArray = _myArray;
#end
So you can use "self.myArray" only in "MyClass.h" file.

Define #property in Protocol

I have a number of UIViewController subclasses and I want them to share the same property called session which handles a "is logged in" state.
I know that I could use a parent class but this is very explicit and so I was wondering if I could "enforce" the session property via a shared protocol.
I have never seen an explicit property defined in a protocol (obviously you could define the setter and getter), so is defining a property inside a protocol an advisable pattern?
#property can also appear in the declaration of a protocol or category.
Stated in the official apple documentation. So no problem there.
Yes, using a protocol it's possible to add a property:
#protocol MyProtocol <NSObject>
#property (nonatomic, retain) NSFoobar *baz;
#end
And #synthesize baz; in every class that adopts this protocol (or you can mark the declared property as optional using the #optional keyword).
You can have properties in a protocol, provided every class that conforms to your protocol have a corresponding #synthesize for that property, or provide a getter and setter.
In .h file:
#property(nonatomic,strong)UILabel *mylabel;
In .m file:
#synthesize mylabel = _mylabel;
compiler will create getter and setter for mylabel.
Ex ->
-(void)setMylabe:(UILabel *) mylabel { //setter
}
-(UIlabel*)mylabel { // getter
}

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

Object as a data member in Objective C

From what I have experienced it seems as if objects cannot be shared data members in objective c. I know you can init a pointer and alloc the object in each method but I cannot seem to figure out how one can say define a NSMutableString as a data member and allow all of the methods to use and modify its data as in c++. Is this true or am I missing something?
To define an instance variable (member), edit your .h file:
#interface MyClass : NSObject {
// ivars go here
NSObject *member;
}
// methods go here
#end
Then, in your .m file, from any instance method (one which begins with -), you can access this variable.
- (void)doThingWithIvar {
[member doThing];
}
If you want to access the variable from outside the object itself, you'll need accessors. You can do this easily with Obj-C properties:
#interface MyClass : NSObject {
// ivars go here
NSObject *member;
}
// methods go here
#property (nonatomic, retain) NSObject *member;
#end
And in the .m:
#implementation MyClass
#synthesize member;
// ...
#end
The #synthesize line creates getter/setter methods for the ivar. Then you can use property syntax:
MyClass *thing = ...;
NSLog(#"%#", thing.member); // getting
thing.member = obj; // setting
(Note that I specified (retain) for the #property; if your member isn't an Objective-C object you won't want that. And if your property's class has a mutable counterpart, you'll want (copy) instead.)
It sounds like you want to synthesize (create getter/setter methods) a property for a member variable. I just found this cheat sheet, go down to the section called, "Properties", should give a quick overview.
Other than that Apple's documentation should give you more info.