I have a class called MyClass which has a small nested inner class called MyInnerClass. The implementation file looks like the following (and also contains an ivar of the nested inner class) :
#class MyInnerClass;
#interface MyClass
{
MyInnerClass *myInnerClassIvar;
}
#property(nonatomic, retain) MyInnerClass *myInnerClassIvar;
#end
Then in the implementation file, I implement both MyClass and MyInnerClass. Looks like the following:
#interface MyInnerClass
{
iVar *x;
}
#property(nonatomic, retain) iVar *x;
#end
#implementation MyInnerClass
#synthesize x;
...
#end
#implementation MyClass
#synthesize myInnerClassIvar;
...
#end
I am now creating a subclass for MyClass, and in it I'm trying to make a call like this:
self.myInnerClassIvar.x
And I'm getting the following message:
Property x cannot be found in in forward class object MyInnerClass *
Am I forgetting something? Haven't implemented an inner class before, see no reason why this shouldn't work.
UPDATED: I moved the interface of MyInnerClass to the .h of MyClass and everything works. Is this a good solution?
I believe that Objective-C does not have inner classes in the sense that you are trying to implement. See SO. But regarding your question...
in MyClass.h there is no mention of the iVars of MyInnerClass - it is a forward definition, i.e. #class MyInnerClass therefore MySubClass has no reference point for x.
If you define two classes MyClass & MyInnerClass (probably a bad thing to name it that considering...) - have them in two separate .h files and two separate .m files (ie. as normal). Make an #property in MyClass of type MyInnerClass. Then in MySubClass you need to import both MyClass & MyInnerClass.
I moved the interface of MyInnerClass into the .h file of MyClass like following:
MyClass.h
#class MyInnerClass;
#interface MyClass
{
MyInnerClass *myInnerClassIvar;
}
#property(nonatomic, retain) MyInnerClass *myInnerClassIvar;
#end
#interface MyInnerClass
{
iVar *x;
}
#property(nonatomic, retain) iVar *x;
#end
I'll wait before I check this off as the answer because based on the previous answer, I know there is some skepticism. The only reason I tried this is because I saw it in the Apple example SimpleTextInput, except in that one the entire inner class is in the .m file. Anyway, would be interested to hear what people have to say about this, if it might incur unwanted side effects later or if its ok.
Related
You can declare a variable like this.
Case1:
#interface MyClass : NSObject
{
NSString *str;
}
#end
Also, if you want to set its property, you can do
Case2:
#interface MyClass : NSObject
{
NSString *str;
}
#property (nonatomic, strong) NSString *str;
#end
And in the .m,
#synthesize str;
My understanding with the difference between Case 1 and Case 2 is that synthesized and propertied variables in Case 2 can be accessed from another class when this another class instantiates this class.
What are other differences between Case 1 and 2? Say when these variables are just used only in its .m file. The fact that you are setting 'str' properties probably makes a difference, but how? If you don't set property, how are they going to be released with ARC?
The differences are fairly confusing in this case because of the way it is set up.
Also it is using what is now old practises.
The new suggested way of doing this (suggested by Apple) is to do this...
MyClass.h
#interface MyClass : NSObject
#property (nonatomic, strong) NSString *str;
#end
MyClass.m
#import "MyClass.h"
#implementation MyClass
#end
You no longer need the #synthesize as Xcode (since 4.5) will auto generate these for you.
Doing this sets up the property called str and an iVar called _str.
You now no longer need to worry about defining multiple ivars and properties etc... Just use the property and that's it done.
An example setter method for the property str would look like this...
- (void)setStr:(NSString*)str
{
_str = str;
}
Here's my question.
Let's say I have a class called WebServiceBase.h. And I need to add a iVar in to that class called NSString *requestData. But I don't need to add that iVar in to the header file and make it visible to the external people. (If I'm distributing this as a class library)
Also I need to be able to access this requestData iVar, within the other classes that is extended from the WebServiceBase.h. (These extended classes are written by me. Not from the external people)
I tried with declaring the requestData iVar within the class extensions. But then it's not visible to the extended classes.
Any solution for this? I need to protect my data and make it hide from the external world.
You can define your ivars as protected via the #protected keyword, meaning that your class and all subclasses can access it without any problem, but the compiler won't allow this for other classes which don't inherit from your base class:
#interface Foo : NSObject
{
#protected
NSObject *a;
}
Its as simple as that and already gives you all the safety you can get from Objective-C.
You can have an ivar definition block in the #implementation block.
there are 2 ways , you can choose one you like.
1).h file
#interface YourClass
{
}
.m file
#interface YourClass ()
#property (nonatomic, retain) NSString *title;
#end
#implementation YourClass
#synthesize title;
//your method
2) .h flie
#interface YourClass
{
}
.m file
#implementation YourClass
{
NSString *title;
}
//your method
Declare a class extension that defines the ivar in another .h file. Call it something like myclass-private.h. Then import that header in both your main class your subclasses.
So basically I have a protocol inside my interface that I need to include in my implementation because I am getting an incomplete error and therefore can't continue.
. h file
#interface waveLayer1 : CCLayer <GameKitHelperProtocol>
{
...
}
.m file
#implementation waveLayer1
GameKitHelper.h file
#import "cocos2d.h"
#import <GameKit/GameKit.h>
#protocol GameKitHelperProtocol
-(void) onLocalPlayerAuthenticationChanged;
-(void) onFriendListReceived: (NSArray*)friends;
-(void) onPlayerInfoReceived:(NSArray*)players;
#end
#interface GameKitHelper : NSObject {
id<GameKitHelperProtocol> delegate; bool isGameCenterAvailable; NSError* lastError;
}
#property (nonatomic, retain) id<GameKitHelperProtocol> delegate;
#property (nonatomic, readonly) bool isGameCenterAvailable; #property (nonatomic, readonly) NSError* lastError;
+(GameKitHelper*) sharedGameKitHelper;
// Player authentication, info
-(void) authenticateLocalPlayer;
-(void) getLocalPlayerFriends;
-(void) getPlayerInfo:(NSArray*)players;
#end
The error is "Method in protocol not implemented" I have more files I can show ,but to save room I decided to see if you can help me fix this with just these codes
#interface waveLayer1 : CCLayer <GameKitHelperProtocol>
This says that "wavelayer1" implements the protocol "GameKitHelperProtocol".
Method in protocol not implemented
says that a method declared in a protocol has not been implemented. Chances are that you forgot to implement one of the "GameKitHelperProtocol" methods, which makes your class NOT implement that protocol, which violates the declaration you made, which causes the compiler to output an error.
Implement these 3 methods in your waveLayer1 class..
-(void) onLocalPlayerAuthenticationChanged;
-(void) onFriendListReceived:(NSArray*)friends;
-(void) onPlayerInfoReceived:(NSArray*)players;
When you declare that a class adopts a protocol, you must write an implementation for all required methods that are defined in that protocol. So in this case, you need to add method implementations that are defined in GameKitHelperProtocol.
I must be asleep already or something because I'm seeing weird things.
I've got a class, called ListSorter (.h/.m), which has 2 extern methods.
The .h looks like:
#interface ListSorter : NSObject {
BOOL eersteKeer;
Menu_Versie_DrieAppDelegate *appDelegate;
}
-(void)convertList;
-(void)addItemToAlertList:item;
-(void)addItemToHistoryList:item;
In an other class, I've imported ListSorter.h in the .h-file, and made an instance of it:
#import "ListSorter.h"
#class ListSorter;
#interface CloseIncController : UIViewController {
ListSorter *sorter;
}
#property (nonatomic, retain) ListSorter *sorter;
So, in the .m-file, I've got:
#synthesize sorter;
...
//Somewhere down in an IB-action
[sorter addItemToHistoryList:keuze];
I NSLogged both addItemToAlertList and addItemToHistoryList, but it always calls addItemToAlertList. Why's that?
you can add multiple action to a button, check if you don't add addItemToAlertList and addItemToHistoryList to the same button
Solved it temporarily by creating two classes, both with one of the methods. My guess is the class didn't get allocated properly.
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.