I want to declare a C++ property inside my Objective-C class.
What kind of attributes should I set it to? It seems that strong or retain will lead to an error saying that it is not an object.
How could I manage its memory properly?
You are right, the property cannot be weak, strong, or retained; for that it would have to be a pointer to an Objective-C object. If you don't use any attributes on a C++ property, it will default to unsafe_unretained,assign,atomic.
A few other things to consider, assuming the Objective-C(++) object controls the lifetime of the C++ property:
Because you can't do much with a C++ object in Objective-C, the
property is mostly useful in Objective-C++ code, where you can mix
Objective-C and C++.
Because you have to manage the property's memory on your own, you
need a custom setter.
Because the property defaults to atomic, you need to use
synchronization in the setter and need a custom getter, too. You
could declare it nonatomic, in which case you would not need to
synchronize and would not need a custom getter.
You can implement dealloc to ensure the C++ object is freed when
the Objective-C++ object goes away.
Here's some useful documentation from Apple: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html.
And here is a quick example. Let's say the C++ class you are using for the property is called MyCPP. In a header you could have:
#interface ClassOCPP : NSObject
// This property can only be used in Objective-C++ code
#ifdef __cplusplus
#property /*(unsafe_unretained,assign,atomic)*/ MyCPP * myCPP;
#endif
// Other stuff may be usable in regular Objective-C code.
#end
Implementation could be as follows (in a .mm file; remember, it's Objective-C++):
#implementation ClassOCPP
{
MyCPP * _myCPP;
}
-(id)init {
self = [super init];
_myCPP = NULL;
return self;
}
-(void)setMyCPP:(MyCPP*)newVal {
#synchronized(self) {
delete _myCPP; // it's OK to delete a NULL pointer
_myCPP = newVal;
}
}
-(MyCPP*)myCPP {
return _myCPP;
}
-(void)dealloc {
puts("De-allocating ClassOCPP.");
delete _myCPP;
}
#end
IIRC, you need to manage it like any other C++ object, so just use assign as the attribute, and you should be good.
Related
Summary:
In the example application below, a shared_ptr is being captured in an Objective-C block. The Objective-C block is being assigned to an ivar of a dynamically created class using the Objective-C runtime API object_setIvarWithStrongDefault. When the Objective-C object is deallocated, the shared_ptr is leaking and the C++ object that it is retaining is not deleted. Why is that?
When object_setIvar is used instead, then the leak is prevented but the ivar points to garbage once the block goes out of scope as object_setIvar assumes an assignment of unsafe_unretained.
I assume this has to do with how Objective-C captures C++ objects, copies blocks and how shared_ptr handles being copied, but I was hoping someone could shed some light on this more than the documentation listed below.
References:
Apple's Blocks and Variables Documentation contains a brief section on C++ objects but it's not entirely clear to me how it affects shared pointers.
LLVM's Documentation on Blocks & C++ Support is a bit more detailed than Apple's...
objc-class.mm contains the implementation for object_setIvarWithStrongDefault
Backstory:
This sample code is extracted from a much larger project and has been significantly reduced to the minimum required to show the issue. The project is an Objective-C macOS application. The application contains several monolithic C++ objects that are glorified key/value stores. Each object is an instance of the same class, but templated on the key type. I want to dynamically create an Objective-C class that contains typed property getters which are backed by the C++ class.
(Yes, this could all be done manually by just writing lots-and-lots of getters myself, but I'd prefer not to. The C++ class has enough information to know the names of the properties and their types, thus I'd like to use some meta-programming techniques to "solve" this.)
Notes:
In an ideal world, I'd just be able to define an iVar on an Objective-C class of the appropriate shared_ptr type but I can't figure out how to do that using the Objective-C runtime APIs.
Given this:
std::shared_ptr<BackingStore<T>> backingStore
How do you use this:
class_addIvar and object_setIvar
Since I couldn't figure that out, I decided to just wrap the shared_ptr into an Objective-C block since blocks are first-class objects and can be passed around where an id is expected.
Sample Application:
(Copy/paste into something like CodeRunner to see output)
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <memory>
typedef NSString* (^stringBlock)();
/**
* StoreBridge
*
* Objective-C class that exposes Objective-C properties
* which are "backed" by a C++ object (Store). The implementations
* for each property on this class are dynamically added.
*/
#interface StoreBridge : NSObject
#property(nonatomic, strong, readonly) NSString *storeName;
#end
#implementation StoreBridge
#dynamic storeName;
- (void)dealloc {
NSLog(#"StoreBridge DEALLOC");
}
#end
/**
* BackingStore
*
* C++ class that for this example just exposes a single,
* hard-coded getter function. In reality this class is
* much larger.
*/
class BackingStore {
public:
BackingStore() {
NSLog(#"BackingStore constructor.");
}
~BackingStore() {
NSLog(#"BackingStore destructor.");
}
NSString *name() const {
return #"Amazon";
}
// Given a shared_ptr to a BackingStore instance, this method
// will dynamically create a new Objective-C class. The new
// class will contain Objective-C properties that are backed
// by the given BackingStore.
//
// Much of this code is hard-coded for this example. In reality,
// a much larger number of properties are dynamically created
// with different return types and a new class pair is
// only created if necessary.
static id makeBridge(std::shared_ptr<BackingStore> storePtr) {
// For this example, just create a new class pair each time.
NSString *klassName = NSUUID.UUID.UUIDString;
Class klass = objc_allocateClassPair(StoreBridge.class, klassName.UTF8String, 0);
// For this example, use hard-coded values and a single iVar definition. The
// iVar will store an Objective-C block as an 'id'.
size_t ivarSize = sizeof(id);
NSString *ivarName = #"_storeNameIvar";
NSString *encoding = [NSString stringWithFormat:#"%s#", #encode(id)];
SEL selector = #selector(storeName);
// Implementation for #property.storeName on StoreBridge. This
// implementation will read the block stored in the instances
// iVar named "_storeNameIvar" and call it. Fixed casting to
// type 'stringBlock' is used for this example only.
IMP implementation = imp_implementationWithBlock((id) ^id(id _self) {
Ivar iv = class_getInstanceVariable([_self class], ivarName.UTF8String);
id obj = object_getIvar(_self, iv);
return ((stringBlock)obj)();
});
// Add iVar definition and property implementation to newly created class pair.
class_addIvar(klass, ivarName.UTF8String, ivarSize, rint(log2(ivarSize)), #encode(id));
class_addMethod(klass, selector, implementation, encoding.UTF8String);
objc_registerClassPair(klass);
// Create instance of the newly defined class.
id bridge = [[klass alloc] init];
// Capture storePtr in an Objective-C block. This is the block that
// will be stored in the instance's iVar. Each bridge instance has
// its own backingStore, therefore the storePtr must be set on the
// instance's iVar and not captured in the implementation above.
id block = ^NSString* { return storePtr->name(); };
Ivar iva = class_getInstanceVariable(klass, ivarName.UTF8String);
// Assign block to previously declared iVar. When the strongDefault
// method is used, the shared_ptr will leak and the BackingStore
// will never get deallocated. When object_setIvar() is used,
// the BackingStore will get deallocated but crashes at
// runtime as 'block' is not retained anywhere.
//
// The documentation for object_setIvar() says that if 'strong'
// or 'weak' is not used, then 'unretained' is used. It might
// "work" in this example, but in a larger program it crashes
// as 'block' goes out of scope.
#define USE_STRONG_SETTER 1
#if USE_STRONG_SETTER
object_setIvarWithStrongDefault(bridge, iva, block);
#else
object_setIvar(bridge, iva, block);
#endif
return bridge;
}
};
int main(int argc, char *argv[]) {
#autoreleasepool {
std::shared_ptr<BackingStore> storePtr = std::make_shared<BackingStore>();
StoreBridge *bridge = BackingStore::makeBridge(storePtr);
NSLog(#"bridge.storeName: %#", bridge.storeName);
// When USE_STRONG_SETTER is 1, output is:
//
// > BackingStore constructor.
// > bridge.storeName: Amazon
// > StoreBridge DEALLOC
// When USE_STRONG_SETTER is 0, output is:
//
// > BackingStore constructor.
// > bridge.storeName: Amazon
// > BackingStore destructor.
// > StoreBridge DEALLOC
}
}
Let's jump in a time machine real quick, C.A. 2010. It's a simpler time, before having to deal with multi-architecture slices, 64 bits, and other fancy things, like importantly ARC.
In this seemingly distant world to today, when you had memory, you had to release it yourself gasp. This meant, that if you had an iVar on your class, you had to explicitly, inside dealloc call release on it.
Well, this doesn't actually change with ARC. The only thing that changes is that the compiler generates all of those nice release calls for you inside of dealloc, even if you don't define the method. How nice.
The problem here, however, is that the compiler doesn't actually know about your iVar containing the block - it's completely defined at runtime. So how could the compiler release the memory?
The answer is it doesn't. You'll need to do some magic to make sure that you release this stuff at run-time. My suggestion would be to iterate over the iVars of the class, and set them to nil, rather than call objc_release directly (as it causes much weeping and gnashing of teeth if you're using ARC).
Something like this:
for (ivar in class) {
if ivar_type == #encode(id) {
objc_setIvar(self, ivar, nil)
}
}
Now, if you ever go in and add an intentionally __unsafe_unretained ivar to this class you'll possibly have more issues. But you really shouldn't be inheriting from classes like this, mmkay?
I want to pass objective-c++ function pointer to standard c++ so that I can call objective-c method on C++.
Here is what I want to achieve:
//C++ side
class CppSide
{
public:
void(*TestFunction)();
};
//objective-c++ side
#interface InteropController : GLKViewController{
}
-(void) PickFile; //I want to pass PickFile address to TestFunction
#end
Following is what I did, but doesn't work
InteropController* controller = [[InteropController alloc] init];
CppSide* cppSide = new CppSide();
cppSide->TestFunction = [controller methodForSelector:#selector(PickFile:)];
cppSide->TestFunction(); //EXC_BADccess(code=1, address=0x2d)
How should I do?
The lazy, easy way is to pass an std::function that calls the objC code (eg, with a lambda).
However, what you have there is a raw C function pointer. You will need to write a C function (or use a non-capturing lambda):
cppSide->TestFunction = [](){ ... ObjC Code here ...};
However, you have no way of referring to the parent scope there - only to the global scope.
If you can change that instead to use an std::function, you will have much more flexibility:
cppSide->TestFunction = [=](){[controller PickFile: ... ];};
If you can't, for some reason, change that function pointer type, consider changing it so that it at the very least expects a data pointer:
class CppSide
{
public:
void(*TestFunction)(void *data);
};
And then you can do:
cppSide->TestFunction = [](void *data) {
InteropController* controller = static_cast<InteropController*>(data);
[controller PickFile: ... ];
}
The caller that invokes the function pointer then needs to explicitly pass a controller.
Right now my OS X 10.9 project is set up with a GUI in Objective-C and all the processing in a C++ class. This doesn't seem like the best way, but this was given to me and I have to work with these constraints. I currently have a NSSlider in the Cocoa GUI. I want to be able to have this NSSlider control a variable x in the C++ class.
Currently the tolerance bar is working when I run the program (working meaning it's continuously updating its value as per my sliding).
Header for NSSlider (Slider.h):
#interface Slider : NSObject {
#private
__weak IBOutlet NSTextField *sliderValue;
__weak IBOutlet NSSlider *slider;
}
- (IBAction)updateSliderValue:(id)sender;
#end
Implementation for the NSSlider (Slider.mm):
#import "Slider.h" // The NSSlider object
#import "CMain.h" // The C++ class that does all the processing (not sure if this is the way to include a C++ interface in an Objective-C++ class or if this will allow me to call its methods)
#implementation Slider
-(void) awakeFromNib {
[slider setIntValue:40];
[sliderValue setIntValue:[slider intValue]];
}
- (IBAction)updateSliderValue:(id)sender {
[sliderValue setIntValue:[slider intValue]];
// Here is where I'd think that if I have a setValueofX(int number) method in the C++ class
// I could call this somehow using objective-C++. I don't know if I can or how to call this method here
}
Here is the relevant snippet from Main.h:
class CMain(){
public:
CMain();
void setValueofX(int number);
int getValueofX();
private:
int x;
};
How do I include CMain.h in the Objective-C++ (which, the .h file or .mm file? and how?) such that it would allow me to call the methods in CMain.h? How would I phrase the method call in Objective-C to set x's value using the setValueofX(sliderValue)?
Please let me know if more information is needed! Any help or thoughts are appreciated!
Thanks!
The code for calling the setter is the same as it would be in C++. However, you'd need a pointer to the CMain object to be able to call the method on it. I don't know where that object currently resides. If there is no object yet in another object, you probably want to create one, which you can by just declaring an instance variable CMain myCMain; and then calling myCMain.setValueOfX( [slider intValue] ); in updateSliderValue:.
As to where to include the C++ class, it's really your choice. However, if you use any C++ in your header, it will take a bunch of careful extra work to include it from plain .m files. So in general I try to stick to plain C and ObjC in the header, and only use C++ in the .mm file. You can use a class extension (sometimes called "class continuation" as well) to declare additional ivars in your .mm file to keep them out of the header.
If you want more info about ObjC++, I answered in detail on another post: Can I separate C++ main function and classes from Objective-C and/or C routines at compile and link? and that also links to a Podcast I was a guest on where I talk about a lot of the details and tricks for integrating ObjC and C++.
Aside: I hope these are not actual names and comments you're using. Never have an ObjC class without a prefix (3 letters, Apple stated they reserve all 2-letter prefixes for their own use, and they've used un-prefixed internal class names in the past which broke some peoples' programs). Also, "Slider" is a bad name, as NSSlider is the actual slider, and this sounds like it should be a subclass. You really want to call this an ISTSliderController or whatever.
I found a solution by noting that there was an existing wrapper class CWrapper.h and it was an objective-C++ implementation class CWrapper.mm. There was a CMain variable instantiated as cmain. I made a getter method for x and I simply created a static method in the wrapper class + (void) passX:(int) number; that I called in the slider class. I chose a static method because this for this application, this value will never have to be different between objects. I hope I made the right choice here!
See code changes below:
I added this to the Slider.h file.
- (int)X;
I added the getter and [CWrapper passX:[self getX]]; to the updateSliderValue method in the Slider.mm file.
- (int)X {
return [slider intValue];
}
- (IBAction)updateSliderValue:(id)sender {
[sliderValue setIntValue:[slider intValue]];
[CWrapper passX:[self getX]];
}
This is the code I added to CWrapper.h.
+ (void) passX:(int) number;
This is the code I added to CWrapper.mm.
+ (void) passX:(int)num
{
cmain.setValueofX(num);
}
Here's an all objective-c and objective-c++ answer:
CMain.h:
#ifndef Testing_CMain_h
#define Testing_CMain_h
#interface CCMain : NSObject
-(CCMain*) init;
-(void) dealloc;
-(void)setValueofX:(int)number;
-(int)getValueofX;
#end
#endif
CMain.mm:
#import <Foundation/Foundation.h>
#import "CMain.h"
class CMain {
private:
int x;
public:
CMain() : x(0) {}
void setValueofX(int number) {x = number;}
int getValueofX() const {return x;}
};
#interface CCMain ()
#property (nonatomic, assign) CMain* inst;
#end
#implementation CCMain
-(CCMain*) init
{
if (!_inst)
{
_inst = new CMain();
}
return self;
}
-(void) dealloc
{
delete _inst;
_inst = nil;
}
-(void)setValueofX:(int)number
{
_inst->setValueofX(number);
}
-(int)getValueofX
{
return _inst->getValueofX();
}
#end
and if you want to use C-style functions then:
setValueofX(cmain_instance, value);
int val = getValueofX(cmain_instance);
And this works because a C++ class function in C is the same as:
void CMain::MyFunc(int X);
//vs..
void MyFunc(CMain* inst, int X);
Both are the exact same thing.
As I know, c++ object in iOS is allocated in the stack memory. Now I have to add the c++ object into a NSArray, however NSArray cannot store c++ objects directly.
The question is how could I store a c++ object in a NSArray and let the NSArray take ownership of the c++ object so that I could use the c++ object whenever I want.
Thanks for any help!
=========EDIT========
Here are some code snippet:
std::list<ImageTextContent> msgs = body->getMsgs();
std::list<ImageTextContent>::iterator itmsgs0;
for(itmsgs0 = msgs.begin();itmsgs0 != msgs.end();itmsgs0++)
{
ImageTextContent *tmpmsgs = &(*itmsgs0);
ImageTextContentWrapper *itc = [[ImageTextContentWrapper alloc] initWithImageTextContent:tmpmsgs];
[self.dataSource addObject:itc];
}
[self.tableview reloadData];
the cellForRow method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
........
ImageTextContentWrapper *itc = (ImageTextContentWrapper *)[_dataSource objectAtIndex:indextPath.row];
NSString *title = [NSString stringWithCString:(itc.imageTextContent->getTitle()).c_str() encoding:NSUTF8StringEncoding];
cell.titleLabel.text = title;
........
}
ImageTextContentWrapper class:
#interface ImageTextContentWrapper : NSObject
#property (nonatomic, assign) ImageTextContent *imageTextContent;
- (id)initWithImageTextContent:(ImageTextContent *)imageTextContent;
#end
#implementation ImageTextContentWrapper
- (id)initWithImageTextContent:(ImageTextContent *)imageTextContent
{
if (self = [super init])
{
self.imageTextContent = imageTextContent;
}
return self;
}
#end
Create an Objective-C class owning your C++ object, and store objects of this class in NSArray.
A small code example how to wrap a C++ object in a Objective-C class:
For a C++ class CPP which could look like
class CPP {
public:
std::string aName;
CPP(std::string aName) : aName(aName) { }
};
you can create a Objective-C wrapper class ObjectiveC:
// ObjectiveC.h
#interface ObjectiveC : NSObject
{
CPP *cpp;
}
- (id)initWithString:(NSString*)string;
- (void)print;
#end
//ObjectiveC.mm <- this .mm tells Xcode to use the right compiler
#import "ObjectiveC.h"
#implementation ObjectiveC
- (id)initWithString:(NSString*)string
{
self = [super init];
if (self)
{
cpp = new CPP([string UTF8String]);
}
return self;
}
- (void)print
{
NSLog(#"%s", cpp->aName.c_str());
}
#end
Now you can create a NSArray containing indirectly containing the C++ objects:
// main.mm for example (.m -> .mm !)
ObjectiveC *oc1 = [[ObjectiveC alloc] initWithString:#"oc1"];
ObjectiveC *oc2 = [[ObjectiveC alloc] initWithString:#"oc2"];
ObjectiveC *oc3 = [[ObjectiveC alloc] initWithString:#"oc3"];
NSArray *array = [[NSArray alloc] initWithObjects:oc1, oc2, oc3, nil];
for (ObjectiveC *oc in array) {
[oc print];
}
A small remark: You have to change all implementation files containing and interacting with this wrapper files from .m to .mm. The second option is to change the compiler in the Xcode settings.
You're off the mark a little. There are two ways to create C++ objects. On the stack (by declaring it as a local, non-pointer variable) or on the heap (e.g. using operator new or by declaring it as a non-pointer instance variable in an ObjC object).
If you actually have one on the stack, there is no way to (safely) reference it from an ObjC class. In ObjC, all objects are on the heap, so everyone who retains it is guaranteed that it will stay around even if the function in which it is declared returns. And the last one who releases it causes its memory to actually be freed.
You can't give that guarantee with stack objects, as they must go away the moment the function in which they are a local variable returns.
But if you could create your C++ object with operator new and your code would still work, instead of a stack object, then you can just create an ObjC class in an ObjC++ file (.mm suffix instead of straight .m), and put that in an array. If you want to learn more about ObjC++, I recommend you listen to my guest spot on the NSBrief podcast, where I talk about ObjC++ in detail.
Alternately, what reason prevents you from just putting your C++ object in a std::vector instead of an NSArray? What are you hoping to use this NSArray full of C++ objects for?
PS - For completeness' sake, let me also mention that there is +NSNumber numberWithNonretainedPointer: (or maybe it was "unretained") which you could use as a pre-made object for keeping a pointer in an array, but this is not recommended, as it does not call delete on the pointer when it is released, so you have to be very careful or you'll leak C++ objects. Better to make your own class.
I have a C++ class method where i need to call the "detachNewThreadSelector" method with all the parameters.
Here lies the problem, as my class is not objective C i don't have a self pointer. Also i don't see how i will be able to call a class method from the method that i will set as selector.
Please do ask if my question is not clear, i am not from a english speaking country.
Here is some code.
ALuint AudioController::PlayStream(const string& asset)
{
//attach to a thread
[NSThread detachNewThreadSelector:(SEL)selector toTarget:(id)selfwithObject:(id)argument]
}
void AudioController::RotateThread(const string& soundKey)
{
}
As you can see how do i pass the RotateThread method as a selector to the "detachNewThreadSelector" and also where do i get the self pointer.
Any help much appreciated.
Thanks
You can't do this. It isn't as a simple as "Where do I get the self pointer?" The actual question is, "Where do I get something that can respond to messages?" Because a C++ class can't.
Objective-C classes, objects and methods are completely different things from C++ classes, objects and methods. The fact that the two languages use the same terminology and use the things for similar purposes confuses a lot of people, but to be clear: They are totally different things that work in very different ways in the two languages. Case in point: C++ methods are simply called rather than dispatched based on a selector like Objective-C methods. And C++ classes aren't even objects.
You have two real options here:
Create an Objective-C class that has the behavior you want.
Use a C++ concurrency solution.
you may not use c++ object in this manner (as an argument to this NSThread method). if your case is simple (read: few interfaces declared), then you can create a utility (objc) class to handle the message, and to then pass the argument back to the AudioController instance. illustration:
(non-compiled pseudo code follows)
namespace pseudo_object {
template <typename> class reference_counted;
}
#interface MONAudioControllerWorker : NSObject
{
pseudo_object::reference_counted<AudioController> audioController_;
std::string asset_;
}
+ (MONAudioControllerWorker *)newMONAudioControllerWorkerWithAudioController:(pseudo_object::reference_counted<AudioController>&)audioController asset:(const std::string&)asset;
- (void)secondaryWorker;
#end
#implementation MONAudioControllerWorker
+ (MONAudioControllerWorker *)newMONAudioControllerWorkerWithAudioController:(pseudo_object::reference_counted<AudioController>&)audioController asset:(const std::string&)asset
{
/* ... */
}
- (void)secondaryWorker
{
NSAutoreleasePool * pool([NSAutoreleasePool new]);
audioController_->RotateThread(asset_);
[pool release];
}
#end
/* static */
ALuint AudioController::PlayStream(pseudo_object::reference_counted<AudioController>& This, const string& asset)
{
/* attach to a thread */
MONAudioControllerWorker * controller = [MONAudioControllerWorker newMONAudioControllerWorkerWithAudioController:This asset:asset];
[NSThread detachNewThreadSelector:#selector(secondaryWorker) toTarget:controller withObject:0];
[controller release];
}
sometimes it is just easier to create an objc class which may contain a simplified (generic) interface for this purpose (i.e. reusable beyond this object), or to use more traditional threading routines (pthreads). if this is the only case in the project, then it should be fine. otherwise, you end up with many utility classes/symbols and much more to maintain. illustration:
#interface MONAudioControllerWrapper : NSObject
{
AudioController audioController_;
std::string asset_;
}
+ (MONAudioControllerWrapper *)newMONAudioControllerWrapperWithAsset:(const std::string&)asset;
- (void)playStream;
#end
#implementation MONAudioControllerWrapper
+ (MONAudioControllerWrapper *)newMONAudioControllerWrapperWithAsset:(const std::string&)asset
{
/* ... */
}
- (void)secondaryWorker
{
NSAutoreleasePool * pool([NSAutoreleasePool new]);
audioController_->RotateThread(asset_);
[pool release];
}
- (void)playStream
{
[NSThread detachNewThreadSelector:#selector(secondaryWorker) toTarget:self withObject:0];
}
#end
As others have said, you can't use detachThreadWithSelector: passing a C++ object as a target or using a C++ method as the selector.
You have two strategies:
wrap the object and selector with an OBjective-C object and selector e.g.
myAudioControllerWrapper = [[OCAudioControllerWrapper alloc] initWithRealController: this];
// need some code to release once thread is complete
[NSThread detachNewThreadSelector: #selector(wrapperSelector:) target: myAudioControllerWrapper withObject: soundKeyAsNSObject];
and your wrapper selector looks like:
-(void) wrapperSelector: (id) key
{
cppController->rotateThread([key cppObject]);
}
Use some other thread mechanism more in keeping with the C++ paradigm. Grand Central Dispatch might be the one if your platform supports it.