源代码:

- (void)sumer{

    @synchronized(_arr){

        [_arr addObject:@"1"];
    }
}

用clang 重写后输出:

static void _I_Testdd_sumer(Testdd * self, SEL _cmd) {

    { id _rethrow = 0; id _sync_obj = (id)(*(NSMutableArray **)((char *)self + OBJC_IVAR_$_Testdd$_arr)); 

    //enter
objc_sync_enter(_sync_obj);

try {
    struct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}
    ~_SYNC_EXIT() {objc_sync_exit(sync_exit);}
    id sync_exit;
    } _sync_exit(_sync_obj);

        ((void (*)(id, SEL, ObjectType))(void *)objc_msgSend)((id)(*(NSMutableArray **)((char *)self + OBJC_IVAR_$_Testdd$_arr)), sel_registerName("addObject:"), (id)(NSString *)&__NSConstantStringImpl__var_folders_5m_jf1yfr0s54x2_6rf51qlcjp00000gp_T_Testdd_043a95_mi_0);
    } catch (id e) {_rethrow = e;}
{ struct _FIN { _FIN(id reth) : rethrow(reth) {}
    ~_FIN() { if (rethrow) objc_exception_throw(rethrow); }
    id rethrow;
    } _fin_force_rethow(_rethrow);}
}

}

简化代码为:

id _rethrow = 0; 
id _sync_obj = (id)(*(NSMutableArray **)((char *)self + OBJC_IVAR_$_Testdd$_arr)); 
objc_sync_enter(_sync_obj);
try{
     objc_sync_exit(sync_exit);
}catch (id e) { _rethrow = e;}

@synchronized不仅可以实现锁,还可以输出意外。

再查看objc_sync_enter的文档


/** 
 * Begin synchronizing on 'obj'.  
 * Allocates recursive pthread_mutex associated with 'obj' if needed.
 * 
 * @param obj The object to begin synchronizing on.
 * 
 * @return OBJC_SYNC_SUCCESS once lock is acquired.  
 */
OBJC_EXPORT int
objc_sync_enter(id _Nonnull obj)

得知其使用了递归的互斥锁。
再看这里找到 objc-sync 的全部源码,部分如下:


typedef struct SyncData {
    struct SyncData* nextData;
    id               object;
    int              threadCount;  // number of THREADS using this block
    recursive_mutex_t        mutex;
} SyncData;

typedef struct {
    SyncData *data;
    spinlock_t lock;

    char align[64 - sizeof (spinlock_t) - sizeof (SyncData *)];
} SyncList 

// Begin synchronizing on 'obj'. 
// Allocates recursive mutex associated with 'obj' if needed.
// Returns OBJC_SYNC_SUCCESS once lock is acquired.  
int objc_sync_enter(id obj)
{
    int result = OBJC_SYNC_SUCCESS;

    if (obj) {
        SyncData* data = id2data(obj, ACQUIRE);
        require_action_string(data != NULL, done, result = OBJC_SYNC_NOT_INITIALIZED, "id2data failed");

        result = recursive_mutex_lock(&data->mutex);
        require_noerr_string(result, done, "mutex_lock failed");
    } else {
        // @synchronized(nil) does nothing
        if (DebugNilSync) {
            _objc_inform("NIL SYNC DEBUG: @synchronized(nil); set a breakpoint on objc_sync_nil to debug");
        }
        objc_sync_nil();
    }

done: 
    return result;
}

// End synchronizing on 'obj'. 
// Returns OBJC_SYNC_SUCCESS or OBJC_SYNC_NOT_OWNING_THREAD_ERROR
int objc_sync_exit(id obj)
{
    int result = OBJC_SYNC_SUCCESS;

    if (obj) {
        SyncData* data = id2data(obj, RELEASE); 
        require_action_string(data != NULL, done, result = OBJC_SYNC_NOT_OWNING_THREAD_ERROR, "id2data failed");

        result = recursive_mutex_unlock(&data->mutex);
        require_noerr_string(result, done, "mutex_unlock failed");
    } else {
        // @synchronized(nil) does nothing
    }

done:
    if ( result == RECURSIVE_MUTEX_NOT_LOCKED )
         result = OBJC_SYNC_NOT_OWNING_THREAD_ERROR;

    return result;
}

以上可以看到加锁,解锁操作。同时Spinlock prevents multiple threads from creating multiple locks for the same new object.