Is this the correct method to prevent more than one thread to access the function MyTaskF?
.h file:
#interface MyInterface : NSObject {
//... some other stuff here
}
.m file:
static NSLock *mytaskMutex;
static MyInterface *MyInterfaceSingleton;
int MyTaskF(int iVar)
{
[mytaskMutex lock];
//do stuff in here
[mytaskMutex unlock];
return 0;
}
Related
Let's say we have following C++ code:
struct ISomeInterface
{
virtual ~ISomeInterface() {}
virtual void f() = 0;
};
class SomeClass : public ISomeInterface
{
public:
void f() override
{
std::cout << "Hi";
}
};
void getObject(ISomeInterface*& ptr)
{
ptr = new SomeClass;
}
int main()
{
ISomeInterface* p(nullptr);
getObject(p);
p->f();
delete p;
}
It's quite straightforward and far from being perfect, but it draws the picture: getting a pointer to an interface to an object via function's parameters.
How do we get the same with Objective C protocols?
#protocol SomeProtocol <NSObject>
- (void)f;
#end
#interface SomeClass : NSObject<SomeProtocol>
- (void)f;
#end
#implementation SomeClass
- (void)f { NSLog(#"Hi"); }
#end
Thanks in advance.
If you actually want the reference parameter, you can do:
void getObject(id<SomeProtocol> *ptr)
{
if (ptr) {
*ptr = [[SomeClass alloc] init];
}
}
int main(int argc, char *argv[])
{
#autoreleasepool {
id<SomeProtocol> p = nil;
getObject(&p);
[p f];
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
C-style function:
id<SomeProtocol> getObject()
{
return [SomeClass new];
}
Objective-C (class) function:
#implementation SomeOtherClass
+ id<SomeProtocol> getObject
{
return [SomeClass new];
}
#end
Consider this code example:
class SomeArbitrarilyNamedClassPlusPlus {
public:
SomeArbitrarilyNamedClassPlusPlus(NSObject *object) { object_ = object; }
SomeArbitrarilyNamedClassPlusPlus() { object_ = nil; }
private:
NSObject *object_;
};
#interface SomeArbitrarilyNamedClassObjective : NSObject
{
SomeArbitrarilyNamedClassPlusPlus *_plusPlusObject;
}
#end
#implementation SomeArbitrarilyNamedClassObjective
-(id)init
{
if ((self = [super init]))
{
_plusPlusObject = new SomeArbitrarilyNamedClassPlusPlus(self);
}
return self;
}
-(void)dealloc
{
NSLog(#"deallocated");
delete _plusPlusObject;
}
#end
int main(int argc, const char * argv[])
{
{
SomeArbitrarilyNamedClassObjective *object = [[SomeArbitrarilyNamedClassObjective alloc] init];
}
return 0;
}
The object variable never gets deallocated. You can check it with Instruments - additional retain counter increment happens inside the -(id)init call.
I would never expect that attributes in C++ classes are strong and this makes me wondering - is there a way to make c++ attributes pointing on Objective-C objects weak?
UPDATE:
There is a way to avoid this using pointers to void in C++ class instead of NSObject* and initialize C++ class in -(id)init method like that:
...
_plusPlusObject = new SomeArbitrarilyNamedClassPlusPlus((__bridge void*)self);
...
However, the question still remains - is there a way to save Objective-C types inside C++ classes but make them weak?
Well, the answer turned out to be quite straightforward - use __weak attribute in C++ class:
class SomeArbitrarilyNamedClassPlusPlus {
public:
SomeArbitrarilyNamedClassPlusPlus(NSObject* object) { object_ = object; }
SomeArbitrarilyNamedClassPlusPlus() { object_ = nil; }
private:
__weak NSObject* object_;
};
I want to create a class in objective-c with already stored data, so that for accessing the data I don't want to instantiate the class. how can I do it?
You can use a singleton or you can use a class made only of class methods and giving you access to static data.
Here is a basic singleton implementation in ObjC:
#interface MySingleton : NSObject
{
}
+ (MySingleton *)sharedSingleton;
#property(nonatomic) int prop;
-(void)method;
#end
#implementation MySingleton
#synthesize prop;
+ (MySingleton *)sharedSingleton
{
static MySingleton *sharedSingleton;
#synchronized(self)
{
if (!sharedSingleton)
sharedSingleton = [[MySingleton alloc] init];
return sharedSingleton;
}
}
-(void)method {
}
#end
and you use it like this:
int a = [MySingleton sharedSingleton].prop
[[MySingleton sharedSingleton] method];
The class method based class would be:
#interface MyGlobalClass : NSObject
+ (int)data;
#end
#implementation MySingleton
static int data = 0;
+ (int)data
{
return data;
}
+ (void)setData:(int)d
{
data = d;
}
#end
In Objective-C, it is possible to pass a class as a parameter to a method:
- (void) methodThatTakesClass:(Class)theClass;
And it is possible to pass an instance that is conforming to a protocol as a parameter:
- (void) myConformInstance:(id <MyProtocol>)theObject;
Is it possible to use the combined functionality? A method which takes a class which is conforming to a certain protocol.
Yes. The following is a valid program which will log the NSObject class.
#import <Foundation/Foundation.h>
void f(Class <NSObject> c) {
NSLog(#"%#",c);
}
int main() {
f([NSObject class]);
}
This would cause a compiler error if you tried to pass a class which doesn't conform to NSObject, such as the Object class. You can also use it for methods.
- (void)printClass:(Class <NSObject>)c;
also valid:
#interface Something: Object {
}
- (void) foo:(int(*)(void))bar;
#end
#implementation Something
- (void) foo:(int(*)(void))bar {
return (*bar)();
}
#end
int someFunc( void ) {
return 9;
}
int main ( int argc, char **argv ) {
Something *object = [[Something alloc] init];
printf( "%i\n", [object foo:&someFunc] );
[object release];
return 0;
}
//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