I found this code in our project and it just feels like the wrong way to do what it seems to be doing

id<NSFastEnumeration> results = [info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for (symbol in results) {
    // this just selects the first symbol in the results

Presumably it actually doesn't select the first symbol - instead it selects the last one!

But there must be a better way. I don't quite know what

[info objectForKey: ZBarReaderControllerResults]

returns, but I'm not too bothered either. Is there a way that I can do the above code without having to loop through all possible results?

  • \$\begingroup\$ I'd have to see the rest of the code (inside the for loop) to tell you what it is doing, but if you simply put a break; command in the loop, then it selects the first symbol. \$\endgroup\$
    – lnafziger
    Jun 13 '13 at 16:20
  • \$\begingroup\$ Hey, there is nothing in the loop. That's just it. Is that the best way? Add a "break"? Is there no way to just select the first object? \$\endgroup\$ Jun 14 '13 at 13:17
  • \$\begingroup\$ Yeah, the best way to get the first object would be to add a break in the loop, unless you know more about the object. I.e. if the results is always an array, then you could cast it to that and use the firstObject method. Unfortunately, the NSFastEnumeration protocol doesn't provide anything like that. \$\endgroup\$
    – lnafziger
    Jun 14 '13 at 14:05

ZBarSDK is the only place I've ever seen NSFastEnumeration. I don't know a whole lot about it, nor do I know exactly why ZBarSDK was designed to be used in this way.

NSFastEnumeration isn't any faster than using a forin loop. It is faster than a regular for or while (or do-while) loop, but not faster than a forin.

In a forin loop, we're using regular Objective-C collections, and NSArray has a firstObject and lastObject.

But if the real question is (and should be) how do I improve this code (more than just specifically grabbing a single object out of an NSFastEnumeration), then the answer is to use AVCaptureMetadataOutput (official documentation), which was introduced in iOS7.

ZBarSDK has an iOS7 memory leak. Also, I don't know about compiled on-device size, but when I removed it from my project, it saved about 1.4mb from the project size.

Meanwhile, AVCaptureMetadataOutput has many advantages over ZBarSDK.

  • It's slightly easier to use... and it's simple to use if you're already familiar with video capture in iOS.
  • It leaves a smaller footprint in terms of storage space your app takes up on a device.
  • Even without ZBarSDK's memory leak, AVCaptureMetadataOutput has a smaller memory footprint.
  • AVCaptureMetadataOutput seems to scan barcodes faster and a farther distances than what I could manage with ZBarSDK.
  • ZBarSDK doesn't support 64-bit processors at all. AVCaptureMetadataOutput however does.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.