On Apr 10, 2011, at 11:53 PM, John Michael Zorko wrote:

> I'm stumped as to why this generates a warning when I compile. Do I need to 
> do something special with my AVURLAsset * to be able to access it from inside 
> the block in order to add it to an NSInvocation?

>        AVURLAsset *asset = [AVURLAsset URLAssetWithURL:streamURL options:nil];

>        [asset loadValuesAsynchronouslyForKeys:[NSArray 
> arrayWithObject:tracks] completionHandler:^
>         {

>             NSInvocation *inv = [NSInvocation 
> invocationWithMethodSignature:sig];

>             [inv setArgument:&asset atIndex:2];       // warning: passing 
> argument 1 of 'setArgument:atIndex:' discards qualifiers from pointer target 
> type

Since asset is a non-__block variable declared outside the block but referenced 
within it, the block holds a const copy of it.  In other words, inside the 
block, "asset" is of type "AVURLAsset * const" -- a const pointer to an 
AVURLAsset.  This is fine and right.

Taking the address of asset yields an expression of type "AVURLAsset * const *".

However, -[NSInvocation setArgument:atIndex:] takes a non-const void* for its 
buffer parameter.  The compiler is telling you that you're passing a 
pointer-to-const in a pointer-to-non-const parameter.  In theory, NSInvocation 
could write through that pointer, thus modifying something through a pointer 
that's not supposed to allow that.

In this case, the warning is not flagging a real problem.  NSInvocation will 
not write through that pointer.  I believe that -setArgument:atIndex: should 
have been declared to take a "const void *" buffer.  You can silence the 
warning by explicitly casting to (void*), like so:

            [inv setArgument:(void*)&asset atIndex:2];


All of that said, since you're already using blocks, you'd almost certainly be 
better off using another block, dispatched to the main queue, rather than using 
NSInvocation or -performSelectorOnMainThread:...

       [asset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:tracks] 
completionHandler:^{
            // Use dispatch_sync if that's really necessary
            dispatch_async(dispatch_get_main_queue(), ^{
                    [self setupPlayerForAsset:asset withIndex:index]; // Wrap 
index in NSNumber if really necessary
            });
        }];

I wasn't sure if the waitUntilDone:YES was strictly necessary.  It seems that 
asynchrony is implicit in the use of -loadValuesAsynchronouslyForKeys:..., so I 
didn't bother translating waitUntilDone:YES into a use of dispatch_sync().  
Also, I suspect that wrapping the index in an NSNumber was intended to 
facilitate the indirect invocation of -setupPlayerForAsset:withIndex: and isn't 
strictly necessary or desired, either.

Regards,
Ken

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to