-
Notifications
You must be signed in to change notification settings - Fork 299
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Repeated fields with primitive non Object types throw an exception when printing #26
Comments
I had the same issue. Just replace the following method in the PBArray.m file: - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len
{
NSUInteger count = 0;
// This is the initialization condition, so we'll do one-time setup here.
// Ensure that you never set state->state back to 0, or use another method to detect initialization
// (such as using one of the values of state->extra).
if(state->state == 0) {
// We are not tracking mutations, so we'll set state->mutationsPtr to point into one of our extra values,
// since these values are not otherwise used by the protocol.
// If your class was mutable, you may choose to use an internal variable that is updated when the class is mutated.
// state->mutationsPtr MUST NOT be NULL.
state->mutationsPtr = &state->extra[0];
}
// Now we provide items, which we track with state->state, and determine if we have finished iterating.
if(state->state < _count) {
// Set state->itemsPtr to the provided buffer.
// Alternate implementations may set state->itemsPtr to an internal C array of objects.
// state->itemsPtr MUST NOT be NULL.
state->itemsPtr = stackbuf;
// Fill in the stack array, either until we've provided all items from the list
// or until we've provided as many items as the stack based buffer will hold.
while((state->state < _count) && (count < len)) {
switch (_valueType) {
case PBArrayValueTypeObject:
stackbuf[count] = ((id *)_data)[state->state];
break;
case PBArrayValueTypeBool:
stackbuf[count] = [NSNumber numberWithBool:((BOOL *)_data)[state->state]];
break;
case PBArrayValueTypeInt32:
stackbuf[count] = [NSNumber numberWithInt:((int32_t *)_data)[state->state]];
break;
case PBArrayValueTypeUInt32:
stackbuf[count] = [NSNumber numberWithUnsignedInt:((uint32_t *)_data)[state->state]];
break;
case PBArrayValueTypeInt64:
stackbuf[count] = [NSNumber numberWithLongLong:((int64_t *)_data)[state->state]];
break;
case PBArrayValueTypeUInt64:
stackbuf[count] = [NSNumber numberWithUnsignedLongLong:((uint64_t *)_data)[state->state]];
break;
case PBArrayValueTypeFloat:
stackbuf[count] = [NSNumber numberWithFloat:((Float32 *)_data)[state->state]];
break;
case PBArrayValueTypeDouble:
stackbuf[count] = [NSNumber numberWithDouble:((Float64 *)_data)[state->state]];
break;
default:
break;
}
state->state++;
count++;
}
}
else {
// We've already provided all our items, so we signal we are done by returning 0.
count = 0;
}
return count;
} This method is a little bit slower than the original one (that just returns the pointer to the _data array) but it works in all cases. If you want you can put a conditional and leave the default implementation if _valueType is equal to PBArrayValueTypeObject but in this way the code is more elegant. |
Thanks! - this works great. I tried to do something similar but was missing the part to set state->itemsPtr to stackbuf. |
I have a message that defines a repeated int64. In the generated MessagePb objective-C class,
the - (void) writeDescriptionTo:(NSMutableString_) output withIndent:(NSString_) indent
method fails since the auto-generated code attempts to do fast enumeration over the items like so
for (NSNumber* value in self.itemsArray) {
[output appendFormat:@"%@%@: %@\n", indent, @"items", value];
}
in this case 'value' is actually of type PBArrayValueTypeInt64, which causes the exception to be thrown in line 186 of PBArray.m
Suggestions on how to fix this to return a new array of NSNumbers around primitive types?
The text was updated successfully, but these errors were encountered: