简体   繁体   中英

Why do I get the error “Array initializer must be an initializer list” when I'm trying to return this array in a function?

I am coming from Java, and I'm very new to Objective C. Anyway, I have this static method which is designed to make a copy of an array (if there's a better way to accomplish this, please let me know, but I'm asking this question more-so to find out why I got this error and how to avoid such an error in the future.) I ran into some problems with it, but just when I thought I had them all sorted out, I got this error that looked like 的XCode

Here is the method in the interface:

+ (float[]) copyArray: (float[]) array withLength: (int) length;

And here is the method in the implementation:

+ (float[]) copyArray: (float[]) array withLength: (int) length
{
    float copiedArray[length];
    for (int i = 0; i < length; i++)
    {
        copiedArray[i] = array[i];
    }
    return copiedArray;
}

If all you really want is to copy the first n elements from one C array into another already existing array, probably the best way is to simply use memcpy :

memcpy(targetArray, sourceArray, sizeof(sourceArray[0]) * numElements);

The sizeof(sourceArray[0]) calculates the byte-size of the type in your array (in your case, it's equivalent to sizeof(float) .

method/function cannot return C array. you should do this

+ (void) copyArrayFrom:(float *)array to:(float *)toArray withLength: (unsigned) length
{
    for (int i = 0; i < length; i++)
    {
        toArray [i] = array[i];
    }
}

C arrays are way more tricky than Java arrays. One of the biggest issues is that in a lot of instances, you don't know how large a C array is unless you have saved this information in a different variable, for example. The C FAQ "Arrays and Pointers" lists a lot of traps and they apply to Objective-C as well. You might want to see question 6.5 in particular.

As @lwxted already suggested, try to avoid C arrays unless you really know what you're doing and you have determined that you need them. C arrays are faster than NSArray but unless you have determined that your array really is a performance bottleneck by measuring with a profiler you will most likely not notice any difference.

And I strongly recommend avoiding a C array of Objective-C objects ( id objects[] ) unless you really, really know very well what you are doing (memory management issues).

In Objective-C, unless for particular needs, a better way to handle this usually is to use the NSArray as opposed to C arrays.

[NSArray arrayWithArray: array];

will copy an array .

Besides, in this case, if you insist on using C arrays, the use of implicitly typed length float[] is advised against. A better way is to use pointers to manipulate arrays.

Also, the stack-allocated array would be invalid after leaving the function, since it's local only in the scope of the copyArray function. You should dynamically allocate memory, if you wish the array to be valid outside the scope.

While I agree with all the points @DarkDust makes, if you're working with a C API such as OpenGL, there may be situations where using NSArray and NSNumber vs. C arrays of type float will have performance impacts. As always, try to use the simpler approach first, and carefully measure performance before deciding to optimize.

In any case, to answer the original question, here's how to correctly return a copy of a C array:

+ (float *)copyOfCArray:(float *)array withLength:(int)length
{
    float *copyOfArray = malloc(length * sizeof(float));

    for (int i = 0; i < length; i++) {
        copyOfArray[i] = array[i];
    }

    return copyOfArray;
}

Also, there's arguably no need to make the above a method at all. Instead, consider writing it as a C function:

float *CopyArray(float *array, int length)
{
    // Implementation would be the same...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM