How to access a variable from inner class - objective-c

//MainClass.m
#interface InnerClass : NSObject{
}
#end
#implementation InnerClass
-(void)run{
while(isActive){//want to access this variable which defined in MainClass
//do something
}
}
#end
#interface MainClass : NSObject{
BOOL isActive;
}
#end
#implementation MainClass
#end
I have MainClass and it has an inner class (InnerClass). I want to access the boolean type variable (isActive) defined in MainClass class from the inner class. What I am trying to do is that the inner class will run on a separate thread and will keep checking the isActive variable on the main class and if isActive is false then it will stop running the new thread.. Thanks in advance...

Objective-C doesn't have inner classes. Consider making isActive a property of MainClass, give InnerClass a pointer to an instance of MainClass, and let InnerClass simply access the property.

Objective-C doesn't have inner classes as a language construct, however you can do all sorts of tricky things like hiding both the interface and implementation of the "innerclass" in the .m file of the MainClass and having a hidden factory method (not in the interface) on the MainClass that creates the 'innerclass' with a bool* property assigned to &isActive of the main class.
MainClass.h
#interface MainClass : NSObject{
BOOL isActive;
}
#end
MainClass.m
#interface InnerClass : NSObject{
BOOL* isActive;
}
-(id)initWithActive:(BOOL*)isAct){
if (self = [super init]) {
isActive = isAct;
}
return self;
}
#end
#implementation InnerClass
-(void)run{
while(*isActive){//want to access this variable which defined in MainClass
//do something
}
}
#end
#implementation MainClass
//Can use [self newInnerClass] to create a new instance of the innerclass
-(id)newInnerClass{
return [[[InnerClass alloc] initWithActive:&isActive] autorelease];
}
#end

Related

is it possible to have a protected ivar declared in a class extension and have a superclass be able to access it or what to do instead?

I have a class which internally uses an ivar. I don't want to expose the ivar in the public interface of the class (the header) but I declare and use it in the implementation file, like so:
//--------SomeClass.h--------------
#interface SomeClass : NSObject
#end
//--------SomeClass.m--------------
#implementation SomeClass ()
{
#protected
NSMutableDictionary *_privateData;
}
#implementation SomeClass
// ...
#end
Then in a subclass of SomeClass, I try to access _privateData:
//--------SomeSubClass.m--------------
#implementation SomeSubClass
// ...
- (void)someMethod {
NSLog(#"%#", _privateData); // NOPE
NSLog(#"%#", self->_privateData); // NOPE
NSLog(#"%#", super->_privateData); // NOPE
}
// ...
#end
But I can't. Is there a way to do this?
In order to achieve the desired behavior, you should create a subclass header file which declares all of your protected data and #import it in your subclass' .m file.
MammalSubclass.h:
#interface Mammal () {
#protected
NSMutableDictionary *_privateData;
}
//...
#end
Human.m:
#import "Human.h"
#import "MammalSubclass.h"
#implementation Human //subclasses Mammal
- (void)someMethod {
NSLog(#"%#", _privateData);
}
//...
#end

Private methods in objective-c not private

I've created two classes with methods with same name. In one of them it is private, in another - public.
Then somewhere on code i write this:
-(void) doMagic:(id) object {
[(ClassA*)object doSmth];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
ClassB * objB = [[ClassB alloc] init];
[self doMagic:objB];
}
In console i see this:
2012-04-25 23:41:28.183 testmagic[558:403] classB - doSmth
Here's classes' sources:
//.h
#interface ClassA : NSObject
-(void) doSmth;
#end
//.m
#implementation ClassA
-(void)doSmth {
NSLog(#"classA - doSmth");
}
#end
//.h
#interface ClassB : NSObject
#end
//.m
#interface ClassB ()
-(void) doSmth;
#end;
#implementation ClassB
- (void)doSmth {
NSLog(#"classB - doSmth");
}
#end
I know, it's because of "message" nature of methods in Obj-C, and at runtime class possibly do not know which of it's methods are private or public, but here's the question:
How can i make really private method? I heard that with decompiling it's possible to see methods names, so someone can just use my private API. How can i prevent it?
The runtime cannot call what it never knows about. The approach I typically take is to use a static function:
MONObject.h
#interface MONObject : NSObject
// ...
#end
MONObject.m
// 'private' methods and ivars are also visible here
#interface MONObject()
// ...
#end
// typically here:
static void fn(MONObject * const self) {
NSLog(#"%#", [self description]);
}
#implementation MONObject
// ...
// sometimes here:
static void fn2(MONObject * const self) {
NSLog(#"%#", [self description]);
}
#end
A workaround to your problem could be to use a proxy/façade class which internally aggregates an instance of your private class. E.g.:
// .h
#interface FoobarFacade: NSObject
- (void)publicMethod;
#end
// .m
#interface FoobarFacade ()
{
Foobar* impl;
}
#end
#interface Foobar: NSObject
- (void)secretMethod;
#end
#implementation Foobar
- (void)secretMethod { NSLog(#"foobar secret method"); }
#end
#implementation FoobarFacade
- (void)publicMethod {
NSLog(#"façade public method");
[impl secretMethod]; // calling into the secret method
}
#end
Of course this isn't 100% safe either, the runtime puts no barriers as others already told.
Right now you can't have truly private methods. When you are declaring a method in a class extension in the .m file you are just hiding it from being exposed in the public header fle. What you are doing now is considered good design because you are hiding the method from the header file which means people would have to go to some length to find those hidden methods, but they can still find them.
Basically the rule I follow is to put as little as I can into the public header as possible and to put everything else into a class extension. This is all you can really do for now.
If you declare the method in the .h file is public. If you want private visibility you have to declare the method in your .m for example:
#interface ClassB (Private_Methods)
- (void)doSmth;
#end
#implementation ClassB
//Rest of .m

ObjectiveC accessing base class properties in subclass?

I am new to ObjectiveC and I have following inheritance.
#interface CGameEntity : NSObject {
b2Body *entityBody;
}
#property(nonatomic,retain) CCSprite *entitySprite;
-(id)initEntity:(CCNode*)parentNode :(b2World*)world;
#end
implementation :
#implementation CGameEntity
#synthesize entitySprite=entitySprite;
.
.
.
#end
And extended class is as follows :
#interface CPlanet : CGameEntity {
}
#end
implementation is as follows:
#implementation CPlanet
-(id)initEntity:(CCNode*)parentNode :(b2World*)world
{
if((self = [super init]))
{
//cannot access "entitySprite" ????
entitySprite=[CCSprite spriteWithFile:#"planet.png"];
}
return self;
}
#end
In the extended class I cannot access the property "entitySprite".
How can I access properties of the base class ?
Thank you
First of all, replace ...
#synthesize entitySprite=entitySprite;
By ...
#synthesize entitySprite;
Then, replace this line ...
entitySprite=[CCSprite spriteWithFile:#"planet.png"];
By this ...
self.entitySprite = [CCSprite spriteWithFile:#"planet.png"];
This will work =)!

Objective-C multiple inheritance

I have 2 classes one includes methodA and the other include methodB. So in a new class I need to override the methods methodA and methodB. So how do I achieve multiple inheritance in objective C? I am little bit confused with the syntax.
Objective-C doesn't support multiple inheritance, and you don't need it. Use composition:
#interface ClassA : NSObject {
}
-(void)methodA;
#end
#interface ClassB : NSObject {
}
-(void)methodB;
#end
#interface MyClass : NSObject {
ClassA *a;
ClassB *b;
}
-(id)initWithA:(ClassA *)anA b:(ClassB *)aB;
-(void)methodA;
-(void)methodB;
#end
Now you just need to invoke the method on the relevant ivar. It's more code, but there just isn't multiple inheritance as a language feature in objective-C.
This is how I code singletonPattern as "a parent" Basically I used a combination of protocol and category.
The only thing I cannot add is a new "ivar" however, I can push it with associated object.
#import <Foundation/Foundation.h>
#protocol BGSuperSingleton
+(id) singleton1;
+(instancetype)singleton;
#end
#interface NSObject (singleton) <BGSuperSingleton>
#end
static NSMutableDictionary * allTheSingletons;
+(instancetype)singleton
{
return [self singleton1];
}
+(id) singleton1
{
NSString* className = NSStringFromClass([self class]);
if (!allTheSingletons)
{
allTheSingletons = NSMutableDictionary.dictionary;
}
id result = allTheSingletons[className];
//PO(result);
if (result==nil)
{
result = [[[self class] alloc]init];
allTheSingletons[className]=result;
[result additionalInitialization];
}
return result;
}
-(void) additionalInitialization
{
}
Whenever I want a class to "inherit" this BGSuperSingleton I just do:
#import "NSObject+singleton.h"
and add #interface MyNewClass () <BGSuperSingleton>
Do you know about Protocols, protocols is the way to implement the multiple inheritance

Syntax to return an instance in Objective-C

can u please help me how to return an instance of a function which is inherited through interface in Objective-C Language?
#protocol prot1
{
public IDispManager getDispManager;
}
#end
#interface A: NSObject (prot1)
{
}
#end
#implementation A
{
/**
* Provides access to the disp manager.
* #return Instance of the disp manager.
*/
public IDispManager getDispManager;
// how to return an instance of this method
}
#end
Plssss help me out???????
The class would have to hold an object of that class and provide a method to return it. Here's an example along the lines of what you wanted to write:
#protocol Proto
- (DisplayManager *)displayManager;
#end
#interface Foo : NSObject <Proto> {
DisplayManager *displayManager;
}
- (DisplayManager *)displayManager;
#end
#implementation Foo
- (DisplayManager *)displayManager {
return [[displayManager retain] autorelease];
}
#end
Though this probably won't make sense to you without understanding the language more fully.