2

I'm trying to add a dispatch_queue_t to a NSMutableArray like so:

    NSMutableArray* queuesWaitingForTargetQueue = (__bridge NSMutableArray*)dispatch_queue_get_specific(targetQueue, WAITING_QUEUE_LIST_KEY);

    NSLog(@"    dispatch_get_current_queue() = %#x", (unsigned int)dispatch_get_current_queue());
    NSLog(@"    dispatch_get_main_queue()    = %#x", (unsigned int)dispatch_get_main_queue());
    NSLog(@"    currQueueId                  = %#x", (unsigned int)currQueueId);
    NSLog(@"    queuesWaitingForTargetQueue  = %#x (%@)", (unsigned int)queuesWaitingForTargetQueue, NSStringFromClass([queuesWaitingForTargetQueue class]));

    [queuesWaitingForTargetQueue addObject:(__bridge id)currQueueId];

The last line sometimes fails with EXC_BAD_ACCESS:

Thread 1: EXC_BAD_ACCESS (code=1, address=0xc08314eb)

While the output was:

 dispatch_get_current_queue() = 0x2879640
 dispatch_get_main_queue()    = 0x2879640
 currQueueId                  = 0x2879640
 queuesWaitingForTargetQueue  = 0x8672ae0 (__NSArrayM)

What could be wrong here?

Daniel S.
  • 6,458
  • 4
  • 35
  • 78
  • 3
    possible duplicate of [What's the best way to put a c-struct in an NSArray?](http://stackoverflow.com/questions/4516991/whats-the-best-way-to-put-a-c-struct-in-an-nsarray). `dispatch_queue_t` is just a C struct. – rmaddy Nov 21 '13 at 19:52
  • 1
    BTW - use `%p` (without the casts) to log pointers. – rmaddy Nov 21 '13 at 19:54
  • 1
    @rmaddy: `dispatch_queue_t` is actually an Objective-C object, see http://stackoverflow.com/questions/8618632/does-arc-support-dispatch-queues. – Martin R Nov 21 '13 at 20:17
  • @rmaddy, thank you for the hint. The linked solution solved my problem for iOS 5. I've now noticed that the code worked in iOS 7 already before. – Daniel S. Nov 21 '13 at 22:41
  • and the %p is nice :) – Daniel S. Nov 21 '13 at 22:43

2 Answers2

0

Your memory management is going to be a real problem here - your crash is almost for sure a pointer to a previously released object. If you really need to move the array around, then move it back and forth using the high level bridge casts (CFBridging...) from an id to a CFType (like a CFMutableDictionary), then use the CF object as the key. When done, CFRelease the CF object.

David H
  • 40,852
  • 12
  • 92
  • 138
0

Well, no.

If you look up the return type of the various methods you're using, like dispatch_get_current_queue(), they return a value of type dispatch_queue_t. If you look up dispatch_queue_t, the docs say:

dispatch_queue_t A dispatch queue is a lightweight object to which your application submits blocks for subsequent execution.

typedef struct dispatch_queue_s *dispatch_queue_t;

It's a struct. Structs are not objects. NSArrays can only hold objects.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • 4
    `dispatch_queue_t` is actually an Objective-C object, see http://stackoverflow.com/questions/8618632/does-arc-support-dispatch-queues: *"Starting in the iOS 6.0 SDK and the Mac OS X 10.8 SDK, every dispatch object (including a dispatch_queue_t) is also an Objective-C object."* – Martin R Nov 21 '13 at 20:18
  • I think this answer together with Martin's comment is the best explanation for me. I've noticed that my code works in iOS 7 Simulator, but not in iOS 5.1 Simulator. Thanks to both of you! I will adjust my code so it works in both versions. – Daniel S. Nov 21 '13 at 22:22