I need to pass the reference of a view controller to one of the object it creates. I have the following piece of code where I instantiate my object
//Method in OwnerClass
- (void) someMethod{
SomeObject *obj = [[SomeObject alloc] init];
obj.instanceVar = self.iVar;
}
Now in SomeObject I want to access the owner(instance of OwnerClass) which created it.
//Method in SomeObject
- (void) callback{
[ownerObj callMethod] //ownerObj is the instance of OwnerClass that created an instance of SomeObj
}
I want to know how do I access the instance of OwnerClass inside instance of SomeObject. Of course, I can simply write a property inside SomeObject like
#property(nonatomic) OwnerClass *ownerReference;
and assign it when I'm initializing SomeObject and access it from there.
What I want to is if there is any standard way of getting the owner. Something similar to
self.parentViewController
which is Apple's standard way of obtaining the parent of a particular view controller.
There is no general, formal concept of "Ownership" for objects in Objective C or the iOS SDK. So no, there is no standard "magic" way of doing what you want.
it's wrong to pass a reference from view to another view..
if you want to call method in another controller you can use protocols and delegate
Related
// apply borders to the buttons
-(void)viewDidLoad
{
[super viewDidLoad];
[self.hostGameButton MH_applySnapStyle];
[self.joinGameButton MH_applySnapStyle];
[self.singlePlayerGameButton MH_applySnapStyle];
}
I am confused about this piece of code. If self is just referring to the instance of that object and when we use #property it creates an instance called _hostGameButton ... etc; why can't we just use this code instead?
[_hostGameButton MH_applySnapStyle];
You can, it's just not considered good practice or style. It breaks the encapsulation created by using properties, as well as the (usually desirable) KVO notifications the accessors generate. Modern Objective-C practice is to use properties for everything and only access the synthesized ivar in the init, dealloc (if necessary), and lazy accessor methods, if necessary.
Instances are the heart of the action in an Objective-C program. Most of the methods you’ll define when creating your own classes will be instance methods; most of the messages you’ll send in your code will call instance methods.
So when you create instance of something(like uibutton,uitext field) as property you can access
it anywhere in your.m file by using self. But if you create instance of it in a class you can access it only in that class but no where outside.
As per Apple Documentation, if you’re accessing an object’s properties from within its own implementation, in this case you should use self.
Let's say I have a simple app that is loading data into a table view. It then allows you to view details (etc).
My table view controller on first load looks something like this below.
Notice I am not using an "property" declarations for these variables. Is this OK? Are there any disadvantages regarding the way memory is then handled?
#interface TblVC ()
{
MBProgressHUD *hudLoad; // new up loading while I go get data
NSMutableArray *results; // set to results after loading data
CLLocationManager *locManager; // get location in view load
}
#end
#implementation TblVC
{
}
- (void)viewDidLoad
{
// spin up the above variables here which can then be used in other methods inside view controller
}
Just use properties. There is absolutely no reason to use the old-style instance variables anymore.
Apple's documentation on properties goes into detail about the benefits. https://developer.apple.com/library/ios/documentation/cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html
An instance variable is unique to a class. By default, only the class and subclasses can access it. Therefore, as a fundamental principal of object-oriented programming, instance variables (ivars) are private—they are encapsulated by the class.
By contrast, a property is a public value that may or may not correspond to an instance variable. If you want to make an ivar public, you'd probably make a corresponding property. But at the same time, instance variables that you wish to keep private do not have corresponding properties, and so they cannot be accessed from outside of the class. You can also have a calculated property that does not correspond to an ivar…
Without a property, ivars can be kept hidden. In fact, unless an ivar is declared in a public header it is difficult to even determine that such an ivar exists.
A simple analogy would be a shrink-wrapped book. A property might be the title, author or hardcover vs. softcover. The "ivars" would be the actual contents of the book. You don't have access to the actual text until you own the book; you don't have access to the ivars unless you own the class.
How can I get super class instance?
id superObject=super;
Xcode says, "Use of undeclared identifier super"
It's not completely clear to me what you are trying to do, but based partly on your comments to your own question here is a guess.
It seems you may be confused over super in both Objective-C and Java. Both these languages are based on inheritance where a subclass instance is also an instance of its superclass. In neither language is there the concept of a "superclass instance/object". The meaning of super in the two languages is essentially the same, but differs in detail due to the different way the two languages support hiding.
In Objective-C super is a keyword while self, which references the instance a method was called on, is a variable (and the equivalent of Java's this). The super keyword is used to call a method on self but to start the search for the implementation to call in the superclass instead of the current class. It is usually used by an overriding method to call the method it has overridden.
However in your comments you also write:
I want to add a target with a method implemented in super class
which suggests you are trying to use an API which uses the target/action pattern, e.g. NSControl and others.
If the method you wish to call is not overridden in the current class then simply passing self as the target will invoke the superclass method. For example:
#interface Base : NSObject
- (IBAction) actionOne:(id) sender;
- (IBAction) actionTwo:(id) sender;
#end
#interface Child : Base
...
#end
#implementation Child
- (void) setActionFor:(NSControl *)aControl
{
aControl.target = self;
aControl.action = #selector(actionOne:); // actionOne is NOT overridden in Child
}
...
However if your subclass overrides a superclass method and you wish to set the superclass implementation as the action then you must write a method in your subclass which invokes the superclass method. For example, expanding on the previous example and passing Base's actionTwo as an action in a Child method when Child overrides actionTwo:
#implementation Child
// override Base method
- (IBAction) actionTwo:(id)sender { ... }
// provide a way to directly invoke Base method bypassing override
- (IBAction) superActionTwo:(id)sender
{
[super actionTwo:sender];
}
- (void) setActionFor:(NSControl *)aControl
{
aControl.target = self;
aControl.action = #selector(superActionTwo:); // indirectly set Base's actionTwo
}
HTH
Your self in-turn consist your super. You can access your super properties through self.
There isn't a separate object that represents your "super" object. Self is an instance of your class, which is part of a class hierarchy. When you call a method using the super keyword, you're specifying that you want to use your super class's implementation of that method. If your subclass doesn't override a method defined in super, then performing the selector on self will trigger a miss on your class's method lookup table and find the method definition on your superclass.
So, the simple answer is you should be able to accomplish what you're trying to do through self =]
Here you are trying initialize object with a class, not with instance of this class.
May be something like this?
id instance = [super init];
-(void)setFaceView:(FaceView *)faceView
{
_faceView= faceView;
self.faceView.dataSource = self;
}
I just started learning IOS programming with famous Stanford lectures on iTunes. I am currently at lecture 6 and I start to have difficulty catching up with the class.
It is a really basic thing, but I really don't understand how 'self' works. Can anyone teach me what 'self's in this code are doing?
self is an implicit parameter in objective-c of instance methods that refers to the object performing the method - see here: Messages to Self and Super
In this case, self.faceView is a call to the property accessor for faceView that is bound to the instance that runs this method, while the assignment _faceView= faceView; is assigning the input parameter faceView to the iVar _faceView. self.faceView.dataSource = self; assigns the object performing this method to the dataSource property of the object's faceView property.
self is the object itself. when you alloc an object. it sets aside enough memory to hold all the variables that class will use.
when you init the object however you attach that memory to self. self is essentially a "variable" (and i use the term loosely) that gives you access to all the functions of the object you are within.
if you have an object with the following method
+(BOOL) isThisWorking{ return YES;}
you would have to call the method on the class. Self is not involved.
however if you have a method
-(BOOL) isThisWorking{ return YES; }
then you would have a method attached to an instance of a class.
calling the first one would require you to call it on the class object itself.
[MyObject isThisWorking];
calling the second one would require you to call it on an instance.
MyObject *testObject = [[MyObject alloc] init];
[testObject isThisWorking];
when you are in a method within test object you will not have the 'testObject' to call methods on.
self fills that void.
if you come from another programming language you will be familiar with other constructs that do the same thing.
for instance in .net the object is "this"
and in old school vb if i remember correctly the object is "Me"
Typically, I would call another class method like this:
MyClass *class = [[MyClass alloc] init];
[class myMethod];
But the problem is that, it will call the ViewDidLoad. That is a problem for me.
Is there any way to access a property in another method or call a class in another method without calling the ViewDidLoad?
Thanks!
Edit1: So are you are saying that if I do this it will not call my VDL?:
MyClassB *classB = [[[MyClassB alloc] init] autorelease];
[classB.pauseButton setHidden:NO];
Also how about when I call a method will that trigger the ViewDidLoad?
Sure; refactor myMethod to not call viewDidLoad.
That is, if you call method a and method a calls b, but you don't want to call b, then you need to modify the implementation of a to sometimes not call b. Either by modifying a or creating a new method c on the class containing a that doesn't call b.
If the problem is that you are calling a method in the system frameworks and it is calling viewDidLoad when you don't want, then the answer is that you really can't do what you think you want to do. But that is just a symptom; the real answer is that your app's architecture needs to be revisited to better fit with the system's frameworks.
Edit1: So are you are saying that if I do this it will not call my
VDL?:
MyClassB *classB = [[[MyClassB alloc] init] autorelease];
That is creating a new instance of MyClassB. If there is already an instance being displayed on screen, then you most likely do not need a new instance and, yes, that is the reason why viewDidLoad is being called.
Either create an instance variable that can point to the already existing instance of classB or otherwise have a means of grabbing that instance; hang it off the app delegate or something.
Overall, it sounds like you are confused about what it means to instantiate an object vs. simply referring to one and how all that fits into the UIKit model of app creation. It is a bit tricky until you get the hang of it. Study some of the many examples that show how to use view controllers as they will likely have solved a similar problem.
You could create the view controller once and save it in an instance variable, then use the instance variable to call the method or access properties.
eg.
if(self.myClass==nil)
self.myClass = [[MyClass alloc] init];
[self.myClass doStuff];
[self.myClass.pauseButton setHidden:NO];