Search code examples
ios4xcode4objective-c-blocksopenfeint

Block_copy Went Missing


I have an Xcode project which includes OpenFeint as a dependency. OpenFeint has one class that makes two calls to Block_copy() and one call to Block_release(). All was well (as in, I built and ran the project a number of times without incident) until suddenly the compiler started complaining that these functions don't exist. The thing literally broke in between two builds, with no changes to the source code in between.

I have no idea where these functions could have gone, but I've attempted to work around it by providing some placeholder function prototypes, like so:

extern void* Block_copy(const void *aBlock);
extern void Block_release(const void *aBlock);

I'm not sure if those are the correct signatures (the documentation on this topic is sparse, at best), but it's the closest I've been able to find. Sadly, this just causes the linker to complain instead of the compiler.

So any ideas? Is my whole development environment screwed? If not, how do I get it working again?


Solution

  • A temporary workaround is to inline the entire contents of 'Block.h' in the OpenFeint source file. Strangely, trying to #include or #import the file does not work, which may be the whole of the problem.

    In any case, this file should exist at /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator[VERSION].sdk/usr/include/Block.h, and the contents should be:

    #ifndef _Block_H_
    #define _Block_H_
    
    #if !defined(BLOCK_EXPORT)
    #   if defined(__cplusplus)
    #       define BLOCK_EXPORT extern "C" 
    #   else
    #       define BLOCK_EXPORT extern
    #   endif
    #endif
    
    #include <Availability.h>
    #include <TargetConditionals.h>
    
    #if __cplusplus
    extern "C" {
    #endif
    
        // Create a heap based copy of a Block or simply add a reference to an existing one.
        // This must be paired with Block_release to recover memory, even when running
        // under Objective-C Garbage Collection.
        BLOCK_EXPORT void *_Block_copy(const void *aBlock)
        __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
    
        // Lose the reference, and if heap based and last reference, recover the memory
        BLOCK_EXPORT void _Block_release(const void *aBlock)
        __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
    
    
        // Used by the compiler. Do not call this function yourself.
        BLOCK_EXPORT void _Block_object_assign(void *, const void *, const int)
        __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
    
        // Used by the compiler. Do not call this function yourself.
        BLOCK_EXPORT void _Block_object_dispose(const void *, const int)
        __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
    
        // Used by the compiler. Do not use these variables yourself.
        BLOCK_EXPORT void * _NSConcreteGlobalBlock[32]
        __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
        BLOCK_EXPORT void * _NSConcreteStackBlock[32]
        __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
    
    
    #if __cplusplus
    }
    #endif
    
    // Type correct macros
    
    #define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__)))
    #define Block_release(...) _Block_release((const void *)(__VA_ARGS__))
    
    
    #endif