Edit: I just realized for my math below I used 2^32 as UINT32_MAX instead of 2^32 - 1. The rest of my reasoning holds up though.
>Especially with small arrays his implementation will return the the 0th or 1st element much much more often than other elements.
Much, much more often? Correct me if my reasoning is wrong, but for a, say, 6 element array, this bug would make a difference less than 0.0000001% of the time ((UINT32_MAX%6)/UINT32_MAX). For a 3 element array, it would make a difference about 0.000000023% of the time. Maybe you mean by small "less than 100 elements", in which case the worst case is 96 elements, where it happens a whopping 0.0000015% of the time.
Indeed, the problem is only pronounced for large arrays, because that's when there's an opportunity for UINT32_MAX%N to be large (since A%B no case where the 0th and 1st element are significantly skewed ahead of everything else. The bias is characterized by the last few elements of the array being selected significantly less often, but the "significantly" part only kicks in for very big arrays.
In fact, the first array length for which you will even see a difference 0.01% of the time would be 430,142 elements [ed: this holds up even adjusting UINT32_MAX to the correct value]. Considering that this is a framework intended to be used for iOS development, I think once your NSArray has grown that large, you might have more important fish to fry than worrying about a small bias in your randomization.