I am having problem with NSOperationQueue
, if I am adding the same operation for 200 times method is behaving as expected.
But if I increase the for loop to 500 times, parameter are becoming empty when queue will start executing the task. Below is the code snippet.
- (void)someMethod:(char *)param1 {
NSBlockOperation *theOp = [NSBlockOperation blockOperationWithBlock: ^{
// use this paramter and do something
}];
[[MyQueueService sharedMyQueueService] operationQueue] addOperation:theOp];
}
This is how I am invoking the above method
for (int index = 1; index < 500; index++) {
MyClass *classInstance = [[MyClass alloc] init];
NSString *parm1 = [NSString stringWithFormat:@"%d", index];
[classInstance someMethod:(char *)[string cStringUsingEncoding:NSUTF8StringEncoding]];
}
Here is becoming empty i.e "", if i run the same method for 500 time, due to this I am unable to perform other operation. Please help me regarding this.
The problem is not with NSOperationQueue
. The issue is the use of char *
. As the documentation for cStringUsingEncoding
says:
The returned C string is guaranteed to be valid only until either the receiver is freed, or until the current memory is emptied, whichever occurs first. You should copy the C string or use
getCString:maxLength:encoding:
if it needs to store the C string beyond this time.
Bottom line, simple C pointers like char *
do not participate in (automatic) reference counting. Your code is using dangling pointers to unmanaged buffer pointers. This is exceedingly dangerous and when not done properly (as in this case), will lead to undefined behavior. The resulting behavior is dictated whether the memory in question happened to be reused for other purposes in the intervening time, which can lead to unpredictable behavior that changes based upon completely unrelated factors (e.g. the loop count or whatever).
You should try running your app with the "address sanitizer" turned on (found in the scheme settings under the "run" settings, on the diagnostics tab) and it will likely report some of these issues. E.g. when I ran your code with address sanitizer, it reported:
==15249==ERROR: AddressSanitizer: heap-use-after-free on address 0x60300003a458 at pc 0x00010ba3bde6 bp 0x70000e837880 sp 0x70000e837028
For more information, see Address Sanitizer documentation or its introductory video.
The easiest solution is going to be to eliminate the char *
and instead use the int
index value or use an object, such as NSString *
.