There is Call to implicitly-deleted copy constructor of 'std::atomic' error in the following code, also std::mutex is the same case.
I can only use a serial queue to do the sync?
__block std::atomic<bool> balance(false); // Call to implicitly-deleted copy constructor of 'std::atomic<bool>' error
dispatch_block_t work = dispatch_block_create(static_cast<dispatch_block_flags_t>(0), ^{
if (!balance) {
long l = dispatch_semaphore_signal(semaphore);
NSLog(#"task 2 %d", l);
balance = true;
}
});
Could you please help me out? thanks a lot!
Related
I've got stacked on very simple issue. Hasn't been using Objective-C a lot at last time. Could someone help me with:
+(UNAuthorizationStatus) mCheckPermissions {
__block UNAuthorizationStatus oOutput = 0;
UNUserNotificationCenter* oCenter = [UNUserNotificationCenter currentNotificationCenter];
[oCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
oOutput = settings.authorizationStatus;
}];
return oOutput;
}
I need assign the value to oOutput from completion handler. For now it's not assinning value correctly. What am I missing? And please do not reply me something Swift related. The question is about Objective-C.
What you're missing is that getNotificationSettingsWithCompletionHandler is asynchronous.
That means that the "answer" within the block (your settings.authorizationStatus) comes back to you after the entire mCheckPermissions method has finished executing, including the return. The order of execution is like this:
+(UNAuthorizationStatus) mCheckPermissions {
__block UNAuthorizationStatus oOutput = 0;
/* 1 */ UNUserNotificationCenter* oCenter = [UNUserNotificationCenter currentNotificationCenter];
/* 2 */ [oCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
/* 4 */ oOutput = settings.authorizationStatus;
}];
/* 3 */ return oOutput;
}
Therefore it is impossible to return, from the outer method mCheckPermissions, a value that arrives into the block. (Unless you have a time machine in your pocket, so you can dip into the future and find out what the result will be.)
Solution found. Issue closed.
+(UNAuthorizationStatus) mCheckPermissions {
__block UNAuthorizationStatus oOutput = UNAuthorizationStatusNotDetermined;
dispatch_semaphore_t oSemaphore = dispatch_semaphore_create(0);
UNUserNotificationCenter* oCenter = [UNUserNotificationCenter currentNotificationCenter];
[oCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
oOutput = settings.authorizationStatus;
dispatch_semaphore_signal(oSemaphore);
}];
if (![NSThread isMainThread]) {
dispatch_semaphore_wait(oSemaphore,DISPATCH_TIME_FOREVER);
} else {
while (dispatch_semaphore_wait(oSemaphore,DISPATCH_TIME_NOW)) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0]];
}
}
return oOutput;
}
Suppose I have a need for multiple block "calls", for instance a loop in which the block is passed to a another function in each iteration. Do I need to make a new block instance each time I call the function (like Example 1) or can I make one block instance that is called each time (like Example 2)?
//Example 1:
while(true){
void (^block)(NSString* test)=^(NSString* test){
//do something
};
[self callWithBlock: block];
}
//Example 2
void (^block)(NSString* test)=^(NSString* test){
//do something
};
while(true){
[self callWithBlock: block];
}
It compiles and runs fine the second way, but I suspect that any concurrency issues may not be immediately obvious.
You can call blocks as often as you want. But you need to be careful about the context that is captured by the block.
If you have any values that are captured by your block, keep in mind, that unless when specifying them as __block variables, they will be copied.
So for example, this code:
int anInteger = 42;
void (^testBlock)(void) = ^{
NSLog(#"Integer is: %i", anInteger);
};
anInteger = 84;
testBlock();
will print 42, not 84.
If you declare anInteger as __block int anInteger = 42, the storage will be shared and the code will print 84.
So, if you have code that is something like:
int foo = 42;
void (^block)(void) = ^{
NSLog(#"%i", foo);
}
while (true) {
block();
foo++;
}
the behavior will be different from
int foo = 42;
while (true) {
void (^block)(void) = ^{
NSLog(#"%i", foo);
}
block();
foo++;
}
This will also apply to pointers and NSObject variables, when you reassign the variable that holds the pointer or object.
To find out more, have a look at Working with Blocks from the Apple developer documentation.
I'm having a hard time finding good examples on how to use these functions.
static void * kQueue1Key = "key1";
static void * kQueue2Key = "key2";
dispatch_queue_t queue1 = dispatch_queue_create("com.company.queue1", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue2 = dispatch_queue_create("com.company.queue2", DISPATCH_QUEUE_SERIAL);
dispatch_queue_set_specific(queue1, kQueue1Key, (void *)kQueue1Key, NULL);
dispatch_queue_set_specific(queue2, kQueue2Key, (void *)kQueue2Key, NULL);
dispatch_sync(queue1, ^{
if(dispatch_get_specific(kQueue1Key))
{
NSLog(#"I'm expecting this line to run (A)");
dispatch_sync(queue2, ^{
NSLog(#"I'm expecting this line to run (B)");
if(dispatch_get_specific(kQueue2Key))
{
if(dispatch_get_specific(kQueue1Key))
{
NSLog(#"I'm expecting this line to run (C)");
}
else
{
[NSException raise:NSInternalInconsistencyException format:#"Should not end up here (C)"];
}
}
else
{
[NSException raise:NSInternalInconsistencyException format:#"Should not end up here (B)"];
}
});
}
else
{
[NSException raise:NSInternalInconsistencyException format:#"Should not end up here (A)"];
}
});
Result
I'm expecting this line to run (A)
I'm expecting this line to run (B)
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Should not end up here (C)'
Is it expected behavior? If I were to dispatch_sync to queue1 since I'm not on the queue I would deadlock. What am I missing?
Oh here, it popped into my head why you're getting what you're getting. Notes in line:
dispatch_sync(queue1, ^{
When you get to this point, the "current queue" is queue1
if(dispatch_get_specific(kQueue1Key))
You're asking the current queue for the value it has for kQueue1Key, you set that earlier, so it gives it back to you.
{
NSLog(#"I'm expecting this line to run (A)");
dispatch_sync(queue2, ^{
When you get to this point, the "current queue" is now queue2
NSLog(#"I'm expecting this line to run (B)");
if(dispatch_get_specific(kQueue2Key))
You're asking the current queue for the value it has for kQueue2Key, you set that earlier, so it gives it back to you.
{
if(dispatch_get_specific(kQueue1Key))
You're now asking the current queue for the value it has for kQueue1Key. Since the current queue is queue2 and you never set a value with kQueue1Key on queue2 you get back NULL.
{
NSLog(#"I'm expecting this line to run (C)");
}
else
{
[NSException raise:NSInternalInconsistencyException format:#"Should not end up here (C)"];
}
The misunderstanding here is that dispatch_get_specific doesn't traverse the stack of nested queues, it traverses the queue targeting lineage. For instance, if you did this instead,
static void * kQueue1Key = (void*)"key1";
static void * kQueue2Key = (void*)"key2";
dispatch_queue_t queue1 = dispatch_queue_create("com.company.queue1", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue2 = dispatch_queue_create("com.company.queue2", DISPATCH_QUEUE_SERIAL);
dispatch_queue_set_specific(queue1, kQueue1Key, (void *)kQueue1Key, NULL);
dispatch_queue_set_specific(queue2, kQueue2Key, (void *)kQueue2Key, NULL);
// Set Queue2 to target Queue1
dispatch_set_target_queue(queue2, queue1);
dispatch_sync(queue2, ^{
if(dispatch_get_specific(kQueue1Key))
{
NSLog(#"I'm expecting this line to run (A)");
}
else
{
[NSException raise:NSInternalInconsistencyException format:#"Should not end up here (C)"];
}
if(dispatch_get_specific(kQueue2Key))
{
NSLog(#"I'm expecting this line to run (B)");
}
else
{
[NSException raise:NSInternalInconsistencyException format:#"Should not end up here (C)"];
}
});
...the targeting relationship is the one that gets traversed, not the stack relationship. It would be nice if there were something that traversed the stack relationship, but I'm not aware of anything (that you wouldn't have to implement yourself).
As mentioned in my comment, recursive locking using dispatch_sync is, in the general case, not possible due to the possibility of non-default queue targeting. For what it's worth, given/assuming default queue targeting, here is one possible approach:
#import <unordered_set>
#import <pthread.h>
static dispatch_once_t recursiveLockWithDispatchQueueTLSKeyOnceToken;
static pthread_key_t recursiveLockWithDispatchQueueTLSKey;
typedef std::unordered_multiset<const void*> RecursiveLockQueueBag;
static void freeRecursiveLockWithDispatchQueueTLSValue(void* tlsValue)
{
RecursiveLockQueueBag* ms = reinterpret_cast<RecursiveLockQueueBag*>(tlsValue);
if (ms) delete ms;
}
static inline BOOL queueStackCheck(dispatch_queue_t q, BOOL checkAndPushNotPop) // If yes, check and push if not on. If no, pop.
{
dispatch_once(&recursiveLockWithDispatchQueueTLSKeyOnceToken, ^{
pthread_key_create(&recursiveLockWithDispatchQueueTLSKey, freeRecursiveLockWithDispatchQueueTLSValue);
});
RecursiveLockQueueBag* ms = reinterpret_cast<RecursiveLockQueueBag*>(pthread_getspecific(recursiveLockWithDispatchQueueTLSKey));
if (!ms)
{
ms = new RecursiveLockQueueBag();
pthread_setspecific(recursiveLockWithDispatchQueueTLSKey, reinterpret_cast<const void*>(ms));
}
const void* const vpq = reinterpret_cast<const void*>((__bridge const void*)q);
BOOL alreadyOn = NO;
if (checkAndPushNotPop)
{
alreadyOn = (ms->count(vpq) > 0);
if (!alreadyOn)
{
ms->insert(vpq);
}
}
else
{
ms->erase(vpq);
}
return alreadyOn;
}
void dispatch_recursive_sync(dispatch_queue_t queue, dispatch_block_t block)
{
if (queueStackCheck(queue, YES))
{
block();
}
else
{
#try
{
dispatch_sync(queue, block);
}
#finally
{
queueStackCheck(queue, NO);
}
}
}
#implementation MyAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
dispatch_queue_t a = dispatch_queue_create("a", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t b = dispatch_queue_create("b", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t c = dispatch_queue_create("c", DISPATCH_QUEUE_SERIAL);
//dispatch_set_target_queue(a, c);
dispatch_recursive_sync(a, ^{
dispatch_recursive_sync(b, ^{
dispatch_recursive_sync(c, ^{
dispatch_recursive_sync(a, ^{
dispatch_recursive_sync(b, ^{
dispatch_recursive_sync(c, ^{
dispatch_recursive_sync(a, ^{
NSLog(#"got there");
});
});
});
});
});
});
});
}
#end
This is the lowest-overhead implementation I could think of in a few minutes. I used C++ to avoid message sending overhead. It requires that all uses of the queue use this function. This can be useful when there's a private queue protecting internal state of an object (i.e. where the queue is private and therefore guaranteed not to be retargeted, and where you can easily ensure that all consumers of the queue use dispatch_recursive_sync.
I have a questions about blocks in Objective-C.
For example I have this code:
__block int count = 0;
void (^someFunction)(void) = ^(void){
count = 4;
};
count +=2;
What would be the proper way to write the same piece of code so the count will become 6, not 2 ?!
Thank you!
I should probably show the actual code because my previous question was blurry.
EDIT:
__block CMTime lastTime = CMTimeMake(-1, 1);
__block int count = 0;
[_imageGenerator generateCGImagesAsynchronouslyForTimes:stops
completionHandler:^(CMTime requestedTime, CGImageRef image, CMTime actualTime,
AVAssetImageGeneratorResult result, NSError *error)
{
if (result == AVAssetImageGeneratorSucceeded)
{
NSImage *myImage = [[NSImage alloc] initWithCGImage:image size:(NSSize){50.0,50.0}];
[arrOfImages addObject:myImage];
}
if (result == AVAssetImageGeneratorFailed)
{
NSLog(#"Failed with error: %#", [error localizedDescription]);
}
if (result == AVAssetImageGeneratorCancelled)
{
NSLog(#"Canceled");
}
if (arrOfImages.count > 5)
{
NSLog(#"here");
}
count++;
}];
int f = count+1;
after 10 iterations count is 0...why?!?!
You are not executing the block (calling a block someFunctionmight be a misleading thing)
__block int count = 0;
void (^someBlock)(void) = ^{
count = 4;
};
someBlock();
count +=2;
Call block like this:
someFunction();
So that would be:
__block int count = 0;
void (^someFunction)(void) = ^(void){
count = 4;
};
// call block
someFunction();
count +=2;
Look at the name of the method you are calling; generateCGImagesAsynchronouslyForTimes: completionHandler:.
Asynchronously means that it executes in a different thread (likely via a queue and, as #newaccount points, it may likely be re-scheduled for future execution on the current queue/thread) and the method returns immediately. Thus, when you set f=count+1;, the completion block hasn't even been executed yet because none of the image loads in background threads have been completed.
You need to make a call from that completion block back to your code that needs to respond to the completion. i.e.
^() {
....
dispatch_async(dispatch_get_main_queue(), ^{[self heyManAnImageLoadedDude];});
....
}
I am working with a C program to try and use it in my iOS application with as little modification as possible. The C program performs a lot of calculations on a set of inputs.
On the iOS side, I am using the following code to create a thread to run the calculations, and also to have a mechanism to report when it is complete (currently, it updates a UILabel os "testLabel" when complete):
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
char *testChar = startProgram( nx, ny, nz ); // this is where I call the C program
dispatch_async(dispatch_get_main_queue(), ^{
NSString *tempString = [[NSString alloc]initWithCString: testChar ];
testLabel.text = tempString;
[tempString release];
});
});
This seems to work, I get my results, and my UI stays responsive.
However, I am wanting to communicate from the C routine back to the UI while the calculations are going on in order to get status as well as to pass some data back incrementally.
So my C program would be something like this:
char* startProgram( int nx, int ny, int nz )
{
setupEverything(); // this is just pseudo code for clarity
for( int i = 0; i < nz; i++ )
{
doMajorCalculations();
reportBackToUI( someResults ); // This is what I would LIKE to do
}
}
I saw a thread on here about passing "self", but I don't think the "self" if passed above would be my class "self". In addition, I tried that and got an error on the C-side of things, saying that it did not recognize the type "id". I changed the type of "id" to the class name, and it told me the parameter was wrong.
Any ideas on the best way to implement this?
Thank you for your help.
declare a global c void*
void* sipUACObj;
And assign it the objective-c class object in your class initializer
sipUACObj = self;
Now whenever you need to invoke something from C function do the following,
ObjcClass *obj = (ObjcClass*) sipUACObj;
[obj someMethod:arg1 Arg2:arg2];
This will call the corresponding objective-C function and you can invoke ur main UI thread in that function.
You could create a singleton class and assign it to the void pointer in its initialization and then do the needful in ur C function.
Maybe what you want is to have a block as a callback for reporting back partial results to the caller. Something like this:
char* startProgram( int nx, int ny, int nz, void(^reportBackToUI)(int) )
{
setupEverything(); // this is just pseudo code for clarity
for( int i = 0; i < nz; i++ )
{
doMajorCalculations();
reportBackToUI( someResults ); // This is what I would LIKE to do
}
}
Then the client could call startProgram using something like:
return startProgram(42, 12, 20, ^(int someResults) {
dispatch_async(dispatch_get_main_queue(), ^{
// Update UI in some way.
});
});
This way your code will have no dependency on what or how the client do and uses the progress callback for. Also it is nice dependency injection.
If using blocks is not possible (model code might need to be pure C to work on other platforms?) then you can switch the block for a function pointer.