我正在尝试将项目更新为 ARC.虽然我看过一些关于更新到 ARC 的帖子,但我见过的帖子都没有处理这个特定问题.我有多个错误,大多数人说:
I am trying to update a project to ARC. Though I've seen a few posts on updating to ARC, none of the posts I've seen handle this specific issue. I've got multiple errors, most saying:
ARC Issue
Pointer to non-const type 'id' with no explicit ownership
指向直线
CCARRAY_FOREACH(children_, item)
在 CCMenu.m 类中.请帮忙.
in the CCMenu.m class. Please help.
更新:
重新启动 Xcode 后,上述问题在
After restarting Xcode the above issue is no longer found at
CCARRAY_FOREACH(children_, item)
但在我注释为
// Arc Issue
其他几个错误已经浮出水面.警告标志:
Several other errors have surface. The warning sign:
Arc Issue
Destination for this '_builtin__memmove_chk' call is a pointer to ownership-qualified-type 'autoreleasing-id'
出现在代码中调用 memmove 的任何位置.
appears wherever is memmove called in the code.
另一个错误:
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:
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
您使用的 cocos2d 版本似乎与 ARC 不兼容,因为 ccArray 代码缺少 ARC 修复和添加.升级到cocos2d 1.1或更新版本.Cocos2d 1.0.1 可能也可以,但我认为该版本仍然存在一些 ARC 问题.
It looks like you're using a version of cocos2d that isn't compatible with ARC because the ccArray code is missing the ARC fixes and additions. Upgrade to cocos2d 1.1 or newer. Cocos2d 1.0.1 might work as well but I think that version still has some ARC issues.
或者从一个新的开始, 启用 ARC 的 cocos2d 项目,然后将您的代码和资源重新添加到它.
Or start with a fresh, ARC-enabled cocos2d project and then re-add your code and resources to it.
这篇关于更新为 ARC 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!