I have created a custom class of NSObject, and I would like to access some instance variables from my main View Controller to that custom class, how do you do that?
EDIT: Perhaps I was unclear in my first formulation. It is the instance variables from the ViewController class I would like to access, not the ivars from my custom class.
If I got you right, the simplest way is to pass view controller instance during initialization. Just implement initWithViewController:(UIViewController*)vc in your custom class.
You should expose your data as properties in your NSObject subclass. You can find a description of properties at this tutorial: http://rypress.com/tutorials/objective-c/properties.html.
You should better use properties to easy access to some info in your custom class.
They automatically generate iVars.
Also you can access public (declared in .h file) ivars directly:
#interface CustomClass : NSObject
{
NSArray *_array1;
}
#property (nonatomic, strong) NSArray *array2;
CustomClass *instance = [CustomClass new];
NSArray *a1 = instance->_array1;
NSArray *a2 = instance.array2;
Related
i have defined variable in GroupView.h
#interface GroupView()
{
NSMutableArray *chatrooms;
}
#end
#implementation GroupView
Now i want to pass this variable in segue
#interface FriendsViewController ()
#end
#implementation FriendsViewController
else if ([segue.identifier isEqualToString:#"showGroupView"]) {
GroupView *groupView = (GroupView *)segue.destinationViewController;
groupView.chatrooms = [NSMutableArray arrayWithArray:chatrooms];
}
i know that chatrooms has to be property in header file to code this way but it is not
So is there any way to use this variable in segue.
Thanks for help.
chatrooms defined as an ivar like you have done is accessed using -> notation:
groupView->chatrooms = [NSMutableArray arrayWithArray:chatrooms]
This is generally discouraged, though. You should use a property instead:
#interface GroupView
#property (strong) NSMutableArray *chatrooms;
#end
Incidentally, if you're using an NSMutableArray, that indicates that you want to modify the element list of the array directly and not just replace the array wholesale. If you only ever want to replace the array with a whole new array every time, I suggest using NSArray instead.
Another point to make here is that you're attempting to cast the object held at segue.destinationViewController as a GroupView. You have either named a UIViewController subclass in a very misleading way, or you are not accessing the GroupView as a correct member of the UIViewController that is returned to you.
Normally, if you are not building the SDK or something. You don't really have a better reason not to expose it in the header file. However, you can expose the property in the extension and declare a private property in the host class(It's really not able to pass if you just declare a local variable). For example, You have a extension called GroupView+Helper. So, you can pass it into the property exposed in the extension. And then internally translate into the GroupView.
In GroupView.m:
#interface GroupView
#property (strong, nonatomic) NSMutableArray *chatrooms;
#end
In GroupView+Helper.h
#property (strong, nonatomic) NSMutableArray *internalChatrooms;
Also, you need to import the GroupView+Helper in the GroupView.
It will make your chatrooms private and internalChatrooms protected.
Can we initalize dynamically any Modal class. rather than creating any NSObject class with property values as likes string inside that class.
default we do code as like:
in .h file
#interface MyUser : NSObject
#property (nonatomic, strong) NSString *username,*bio,*website;
#end
in .m file
#implementation InstaUser
#synthesize bio;
#end
To use that we do:
MyUser *sendUser = [[MyUser alloc]init];
sendUser.username = #"JHON";
sendUser.bio = #"abcdcskdfhksfjhfkjsdf";
I Don't want to create so many this type of modal class rather then this just any dynamic method to initalize class property and use it by inline code.
You can use run time feature of objective c class.
Create a single model class and add property to it dynamically at run time:
For more reference :
How can I add properties to an object at runtime?
I think you meant a flexible model object with dynamically declared properties something like this:
MyModel *user = [[MyModel alloc] init];
user.name = #"name";
MyModel *something = [[MyModel alloc] init];
something.dynamicProperty = #"blahblah";
If so, you cannot. Use NSMutableDictionary instead, or consider to generate model classes from a simple config file by some scripts.
I have a few different viewControllers that need to inherit the same properties, but aren't the same type of viewController. For example, one VC is a regular UIViewController, whereas another one is a UISplitViewController. Is there any way for me to efficiently use inheritance to make sure they all have these certain properties? Or do I just need to give each one their own separate declarations?
You can achieve what you want using a category on UIViewController. You can implement the properties in the category using associated objects.
See Objective-C: Property / instance variable in category for more details.
You could add a category to UIViewController. Since UISplitViewController inherits from UIViewController, it will have all properties and methods as defined in the category as well. However, categories have two limitations:
You can't add backing instance variables. You can create properties, but they can't have instance variables backing them. That means that if you are overriding the getter (and setter, if readwrite), so that it reads (or writes) an already existing property in some way, you're good. If not, you can look at associated objects.
Overriding methods in a category is a no-no. While nothing stops you from doing it, you have undefined behavior if another category overrides that method too. You just don't know which method will get executed. If you need to override methods, subclassing UIViewController would be better. However, UISplitViewController will then not know about these properties, unless you subclass it as well and add those same properties (in which case you're maintaining these properties twice).
I'm not sure what exactly do you need. If you don't want to (or can't) use common superclass with public properties, you can always write protocol. Only difference is that, protocol don't give you common implementation, but force you to write one (so you can be sure it is there, as you asked for).
Why not set up inheritance using a shared base class and set those shared properties in the init?
//MyBaseVC.h
#interface MyBaseVC : UIViewController
#property (nonatomic, strong) NSString *myString;
#end
//VC1.h
#interface VC1 : MyBaseVC
#end
//VC2.h
#interface VC2 : MyBaseVC
#end
-----
//(MyBaseVC.m)
-(id) init {
self = [super init];
if(self){
self.myString = #"Hello world!";
}
return self;
}
// VC1.m
-(id) init {
self = [super init];
NSLog(#"%#", self.myString); // "Hello world!"
return self;
}
// VC2.m
-(id) init {
self = [super init];
NSLog(#"%#", self.myString); // "Hello world!"
return self;
}
At that point, you can directly refer to the property on the subclassed objects:
NSLog(#"%#",myVc1.myString); //"Hello world!"
Otherwise, when you reference the VCs in a more generic fashion, you can always refer to their super class (MyBaseVC) - for example, if you need to pass them as a method parameter.
//-(void)doSomethingWithVC:(MyBaseVC *)vc;
[someObj doSomethingWithVc: vc1];
I'm working on a project in objective C where i have to modificate some variables which are in a view controller from uiviews.
So i've tried somethings like this :
ViewController.h :
#property (nonatomic) bool Contact;
One of the UIViews :
ViewController * View;
View.Contact = YES;
I've also tried to make a setter method like this in the ViewController :
-(void) SetterContact:(bool)boolean;
And so to modificate from a UIView like this :
[View SetterContact:YES];
But it's looking working.
I've read that i have to init the object in which is containt the variable, but in memory management it's not really good to make some initializations from object who are already actives no ?
So if View is already init, i'm not going to call the init method from another UIView no ?
Thanks for your help !
If you want bool variable to be accessible from other viewController.Then simply wirte it as :-
#property BOOL Contact;
and make an object of ViewController in which you have declared contact variable as BOOL and access this variable using like this:-
OtherViewController *otherViewController=[[OtherViewController alloc] init];
otherViewController.Contact=YES;
As it is a instance variable it has to be accessed using class object.
use #property (nonatomic, assign, getter = isContact) BOOL contact; in your .h file.
Respect naming conventions
#property (nonatomic,retain) UIViewController *myController;
don't forget to synthesize
#synthesize myController = _myController;
If you want to implement your own setter do this: respect the naming convention
-(void)setMyController:(UIViewController*)controller;
or if by any bizarre reason you can't respect naming convention you can point the property to the method you want
#property (nonatomic,retain,setter=myBizarreSetterMethod:) UIViewController *myController;
this can help you out as well question in stackoverflow
I am using forward declaration in the calling Class.
.h file in ClassTwo
#class ClassOne
#property(nonatomic,retain) ClassOne *class_One;
.m file
#synthesize class_One;
Then i am trying to call this method in ClassOne
[self.class_One callingThisMethodFromClassTwo];
On the other hand if i create a shared instance in ClassOne and use it as a class method it works
[[ClassOne Shared] nowItWorks];
Sorry if this is a silly question i am very new
try to allocate class_One instance and add #import "ClassOne.h" to headers on top of your classtwo.m
self.class_One= [[ClassOne alloc]init];
[self.class_One callingThisMethodFromClassTwo];
If [self.class_One callingThisMethodFromClassTwo]; fails... this directly refers that
Either class_One is not alloc+init-ed.
Or callingThisMethodFromClassTwo is a private/protected method.
Or callingThisMethodFromClassTwo is a class method.
I am recommending you to use Protocol/Delegate for this issue.
You Should declare a delegate protocol for your class. An example of a delegate protocol and interface for class Foo might be in this way:
#protocol MyClassDelegate
// Required means if they want to use the delegate they
// have to implement it.
#required
// method that you want to call from another class.
- (void)taskComplete:(BOOL)complete;
#end
#interface MyClass : NSObject
{
// We don't know what kind of class is going to adopt us at
//compile time, that's why this is an id
id delegate;
}
#property (nonatomic, assign) id delegate;
(void)taskComplete;
(void)doSomeTask;
Suppose you have a complex project and don’t want to create lots of
linkages between your classes, in that case delegation like this is going to be your best way to implement. It’s like having function pointers ad callbacks, but the communication goes both ways easily. Time to adopt our protocol and actually use it in a class.
myClass = [[MyClass alloc] init];
// Very important. If we don't let myClass know who the delegate
// is we'll never get the protocol methods called to us.
[myClass setDelegate:self];
In this you can call method from another class. I hope this will help you.