更新为ARC错误

我正在尝试将一个项目更新到ARC。 虽然我已经看到更新到ARC的几个post,但我没有看到任何post处理这个特定的问题。 我有很多错误,大多数人说:

ARC Issue Pointer to non-const type 'id' with no explicit ownership 

指着线

 CCARRAY_FOREACH(children_, item) 

在CCMenu.m类中。 请帮忙。

更新:

重新启动Xcode后,上面的问题不再被发现

 CCARRAY_FOREACH(children_, item) 

但是在ccCArray.h类中我发现了这些行

 // Arc Issue 

还有其他几个错误。 警告标志:

 Arc Issue Destination for this '_builtin__memmove_chk' call is a pointer to ownership-qualified-type 'autoreleasing-id' 

出现在代码中调用memmove的地方。

另一个错误:

 ARC Casting Rules Implicit conversion of C pointer type 'void *' to Objective-C pointer type 'id' requires a bridged cast 

出现在我已经评论为:

 //ARC Casting Rules 

ccCArray.h:

 #ifndef CC_ARRAY_H #define CC_ARRAY_H #import <Foundation/Foundation.h> #import <stdlib.h> #import <string.h> #pragma mark - #pragma mark ccArray for Objects // Easy integration #define CCARRAYDATA_FOREACH(__array__, __object__) \ __object__=__array__->arr[0]; for(NSUInteger i=0, num=__array__->num; i<num; i++, __object__=__array__->arr[i]) \ typedef struct ccArray { NSUInteger num, max; id *arr; // Arc Issue } ccArray; /** Allocates and initializes a new array with specified capacity */ static inline ccArray* ccArrayNew(NSUInteger capacity) { if (capacity == 0) capacity = 1; ccArray *arr = (ccArray*)malloc( sizeof(ccArray) ); // Arc Issue arr->num = 0; arr->arr = (id*) malloc( capacity * sizeof(id) ); arr->max = capacity; return arr; } static inline void ccArrayRemoveAllObjects(ccArray *arr); /** Frees array after removing all remaining objects. Silently ignores nil arr. */ static inline void ccArrayFree(ccArray *arr) { if( arr == nil ) return; ccArrayRemoveAllObjects(arr); free(arr->arr); free(arr); } /** Doubles array capacity */ static inline void ccArrayDoubleCapacity(ccArray *arr) { arr->max *= 2; id *newArr = (id *)realloc( arr->arr, arr->max * sizeof(id) ); // Arc Issue // will fail when there's not enough memory NSCAssert(newArr != NULL, @"ccArrayDoubleCapacity failed. Not enough memory"); arr->arr = newArr; } /** Increases array capacity such that max >= num + extra. */ static inline void ccArrayEnsureExtraCapacity(ccArray *arr, NSUInteger extra) { while (arr->max < arr->num + extra) ccArrayDoubleCapacity(arr); } /** shrinks the array so the memory footprint corresponds with the number of items */ static inline void ccArrayShrink(ccArray *arr) { NSUInteger newSize; //only resize when necessary if (arr->max > arr->num && !(arr->num==0 && arr->max==1)) { if (arr->num!=0) { newSize=arr->num; arr->max=arr->num; } else {//minimum capacity of 1, with 0 elements the array would be free'd by realloc newSize=1; arr->max=1; } arr->arr = (id*) realloc(arr->arr,newSize * sizeof(id) ); // Arc Issue NSCAssert(arr->arr!=NULL,@"could not reallocate the memory"); } } /** Returns index of first occurence of object, NSNotFound if object not found. */ static inline NSUInteger ccArrayGetIndexOfObject(ccArray *arr, id object) { for( NSUInteger i = 0; i < arr->num; i++) if( arr->arr[i] == object ) return i; return NSNotFound; } /** Returns a Boolean value that indicates whether object is present in array. */ static inline BOOL ccArrayContainsObject(ccArray *arr, id object) { return ccArrayGetIndexOfObject(arr, object) != NSNotFound; } /** Appends an object. Bahaviour undefined if array doesn't have enough capacity. */ static inline void ccArrayAppendObject(ccArray *arr, id object) { arr->arr[arr->num] = [object retain]; arr->num++; } /** Appends an object. Capacity of arr is increased if needed. */ static inline void ccArrayAppendObjectWithResize(ccArray *arr, id object) { ccArrayEnsureExtraCapacity(arr, 1); ccArrayAppendObject(arr, object); } /** Appends objects from plusArr to arr. Behaviour undefined if arr doesn't have enough capacity. */ static inline void ccArrayAppendArray(ccArray *arr, ccArray *plusArr) { for( NSUInteger i = 0; i < plusArr->num; i++) ccArrayAppendObject(arr, plusArr->arr[i]); } /** Appends objects from plusArr to arr. Capacity of arr is increased if needed. */ static inline void ccArrayAppendArrayWithResize(ccArray *arr, ccArray *plusArr) { ccArrayEnsureExtraCapacity(arr, plusArr->num); ccArrayAppendArray(arr, plusArr); } /** Inserts an object at index */ static inline void ccArrayInsertObjectAtIndex(ccArray *arr, id object, NSUInteger index) { NSCAssert(index<=arr->num, @"Invalid index. Out of bounds"); ccArrayEnsureExtraCapacity(arr, 1); NSUInteger remaining = arr->num - index; if( remaining > 0) memmove(&arr->arr[index+1], &arr->arr[index], sizeof(id) * remaining ); arr->arr[index] = [object retain]; arr->num++; } /** Swaps two objects */ static inline void ccArraySwapObjectsAtIndexes(ccArray *arr, NSUInteger index1, NSUInteger index2) { NSCAssert(index1 < arr->num, @"(1) Invalid index. Out of bounds"); NSCAssert(index2 < arr->num, @"(2) Invalid index. Out of bounds"); id object1 = arr->arr[index1]; arr->arr[index1] = arr->arr[index2]; arr->arr[index2] = object1; } /** Removes all objects from arr */ static inline void ccArrayRemoveAllObjects(ccArray *arr) { while( arr->num > 0 ) [arr->arr[--arr->num] release]; } /** Removes object at specified index and pushes back all subsequent objects. Behaviour undefined if index outside [0, num-1]. */ static inline void ccArrayRemoveObjectAtIndex(ccArray *arr, NSUInteger index) { [arr->arr[index] release]; arr->num--; NSUInteger remaining = arr->num - index; if(remaining>0) memmove(&arr->arr[index], &arr->arr[index+1], remaining * sizeof(id)); } /** Removes object at specified index and fills the gap with the last object, thereby avoiding the need to push back subsequent objects. Behaviour undefined if index outside [0, num-1]. */ static inline void ccArrayFastRemoveObjectAtIndex(ccArray *arr, NSUInteger index) { [arr->arr[index] release]; NSUInteger last = --arr->num; arr->arr[index] = arr->arr[last]; } static inline void ccArrayFastRemoveObject(ccArray *arr, id object) { NSUInteger index = ccArrayGetIndexOfObject(arr, object); if (index != NSNotFound) ccArrayFastRemoveObjectAtIndex(arr, index); } /** Searches for the first occurance of object and removes it. If object is not found the function has no effect. */ static inline void ccArrayRemoveObject(ccArray *arr, id object) { NSUInteger index = ccArrayGetIndexOfObject(arr, object); if (index != NSNotFound) ccArrayRemoveObjectAtIndex(arr, index); } /** Removes from arr all objects in minusArr. For each object in minusArr, the first matching instance in arr will be removed. */ static inline void ccArrayRemoveArray(ccArray *arr, ccArray *minusArr) { for( NSUInteger i = 0; i < minusArr->num; i++) ccArrayRemoveObject(arr, minusArr->arr[i]); } /** Removes from arr all objects in minusArr. For each object in minusArr, all matching instances in arr will be removed. */ static inline void ccArrayFullRemoveArray(ccArray *arr, ccArray *minusArr) { NSUInteger back = 0; for( NSUInteger i = 0; i < arr->num; i++) { if( ccArrayContainsObject(minusArr, arr->arr[i]) ) { [arr->arr[i] release]; back++; } else arr->arr[i - back] = arr->arr[i]; } arr->num -= back; } /** Sends to each object in arr the message identified by given selector. */ static inline void ccArrayMakeObjectsPerformSelector(ccArray *arr, SEL sel) { for( NSUInteger i = 0; i < arr->num; i++) [arr->arr[i] performSelector:sel]; } static inline void ccArrayMakeObjectsPerformSelectorWithObject(ccArray *arr, SEL sel, id object) { for( NSUInteger i = 0; i < arr->num; i++) [arr->arr[i] performSelector:sel withObject:object]; } #pragma mark - #pragma mark ccCArray for Values (c structures) typedef ccArray ccCArray; static inline void ccCArrayRemoveAllValues(ccCArray *arr); /** Allocates and initializes a new C array with specified capacity */ static inline ccCArray* ccCArrayNew(NSUInteger capacity) { if (capacity == 0) capacity = 1; ccCArray *arr = (ccCArray*)malloc( sizeof(ccCArray) ); arr->num = 0; arr->arr = (id*) malloc( capacity * sizeof(id) ); // Arc Issue arr->max = capacity; return arr; } /** Frees C array after removing all remaining values. Silently ignores nil arr. */ static inline void ccCArrayFree(ccCArray *arr) { if( arr == nil ) return; ccCArrayRemoveAllValues(arr); free(arr->arr); free(arr); } /** Doubles C array capacity */ static inline void ccCArrayDoubleCapacity(ccCArray *arr) { ccArrayDoubleCapacity(arr); } /** Increases array capacity such that max >= num + extra. */ static inline void ccCArrayEnsureExtraCapacity(ccCArray *arr, NSUInteger extra) { ccArrayEnsureExtraCapacity(arr,extra); } /** Returns index of first occurence of value, NSNotFound if value not found. */ static inline NSUInteger ccCArrayGetIndexOfValue(ccCArray *arr, void* value) { for( NSUInteger i = 0; i < arr->num; i++) if( arr->arr[i] == value ) return i; return NSNotFound; } /** Returns a Boolean value that indicates whether value is present in the C array. */ static inline BOOL ccCArrayContainsValue(ccCArray *arr, void* value) { return ccCArrayGetIndexOfValue(arr, value) != NSNotFound; } /** Inserts a value at a certain position. Behaviour undefined if aray doesn't have enough capacity */ static inline void ccCArrayInsertValueAtIndex( ccCArray *arr, void *value, NSUInteger index) { NSCAssert( index < arr->max, @"ccCArrayInsertValueAtIndex: invalid index"); NSUInteger remaining = arr->num - index; // last Value doesn't need to be moved if( remaining > 0) { // tex coordinates memmove( &arr->arr[index+1],&arr->arr[index], sizeof(void*) * remaining ); } arr->num++; arr->arr[index] = (id) value; } /** Appends an value. Bahaviour undefined if array doesn't have enough capacity. */ static inline void ccCArrayAppendValue(ccCArray *arr, void* value) { arr->arr[arr->num] = (id) value; arr->num++; } /** Appends an value. Capacity of arr is increased if needed. */ static inline void ccCArrayAppendValueWithResize(ccCArray *arr, void* value) { ccCArrayEnsureExtraCapacity(arr, 1); ccCArrayAppendValue(arr, value); } /** Appends values from plusArr to arr. Behaviour undefined if arr doesn't have enough capacity. */ static inline void ccCArrayAppendArray(ccCArray *arr, ccCArray *plusArr) { for( NSUInteger i = 0; i < plusArr->num; i++) ccCArrayAppendValue(arr, plusArr->arr[i]); //ARC Casting Rules } /** Appends values from plusArr to arr. Capacity of arr is increased if needed. */ static inline void ccCArrayAppendArrayWithResize(ccCArray *arr, ccCArray *plusArr) { ccCArrayEnsureExtraCapacity(arr, plusArr->num); ccCArrayAppendArray(arr, plusArr); } /** Removes all values from arr */ static inline void ccCArrayRemoveAllValues(ccCArray *arr) { arr->num = 0; } /** Removes value at specified index and pushes back all subsequent values. Behaviour undefined if index outside [0, num-1]. @since v0.99.4 */ static inline void ccCArrayRemoveValueAtIndex(ccCArray *arr, NSUInteger index) { for( NSUInteger last = --arr->num; index < last; index++) arr->arr[index] = arr->arr[index + 1]; } /** Removes value at specified index and fills the gap with the last value, thereby avoiding the need to push back subsequent values. Behaviour undefined if index outside [0, num-1]. @since v0.99.4 */ static inline void ccCArrayFastRemoveValueAtIndex(ccCArray *arr, NSUInteger index) { NSUInteger last = --arr->num; arr->arr[index] = arr->arr[last]; } /** Searches for the first occurance of value and removes it. If value is not found the function has no effect. @since v0.99.4 */ static inline void ccCArrayRemoveValue(ccCArray *arr, void* value) { NSUInteger index = ccCArrayGetIndexOfValue(arr, value); if (index != NSNotFound) ccCArrayRemoveValueAtIndex(arr, index); } /** Removes from arr all values in minusArr. For each Value in minusArr, the first matching instance in arr will be removed. @since v0.99.4 */ static inline void ccCArrayRemoveArray(ccCArray *arr, ccCArray *minusArr) { for( NSUInteger i = 0; i < minusArr->num; i++) ccCArrayRemoveValue(arr, minusArr->arr[i]); //ARC Casting Rules } /** Removes from arr all values in minusArr. For each value in minusArr, all matching instances in arr will be removed. @since v0.99.4 */ static inline void ccCArrayFullRemoveArray(ccCArray *arr, ccCArray *minusArr) { NSUInteger back = 0; for( NSUInteger i = 0; i < arr->num; i++) { if( ccCArrayContainsValue(minusArr, arr->arr[i]) ) //ARC Casting Rules { back++; } else arr->arr[i - back] = arr->arr[i]; } arr->num -= back; } #endif // CC_ARRAY_H 

看起来你正在使用与ARC不兼容的cocos2d版本,因为ccArray代码缺lessARC修复和添加。 升级到cocos2d 1.1或更新版本 。 Cocos2d 1.0.1也可以工作,但我认为该版本仍然有一些ARC问题。

或者从一个新的,启用ARC的cocos2d项目开始 ,然后重新添加你的代码和资源。

轻松修复:

摆脱这个“使用一个原始的Carrays来存储对象” – 方法完全删除包含macros的整个文件。

将其replace为正确使用Foundation框架中的(可变)容器,然后继续。