Finding an index of an object in NSArray using an inline block

I saw several examples related to using NSArray indexOfObjectPassingTest, but I could not get them to work (they will not return a valid index). So now I am trying to use the inline block. I did this by typing a block, then setting it as a property, synthesizing it and initializing it in the constructor. However, this view displays the entire point without sound, since I could easily create a method and use it instead (less typing, less effort).

What I'm trying to achieve is this:

Observations *obs = [self.myAppointment.OBSERVATIONS objectAtIndex: ^NSInteger (NSString *keyword){ for (Observations *obs in self.myAppointment.OBSERVATIONS) { if ([obs.TIME isEqualToString:keyword] == YES) return (NSInteger)[self.myAppointment.OBSERVATIONS indexOfObject:obs]; } return (NSInteger)-1; }]; 

However, Xcode simply will not have it. I tried different options, but declaring its embedded line seems to be a problem, which is strange because, as I said, typing it, declaring and synthesizing it works like this:

 Observations *obs = [self.myAppointment.OBSERVATIONS objectAtIndex:findObs(keyword)]; 

Where findObs is again a specific block that does the same thing. Is this a syntax issue, or am I missing something even more important?

+6
source share
3 answers

-objectAtIndex: takes the NSUInteger parameter as the parameter, but you pass it a block (indicated by the ^ symbol). The second example calls findObs (which may be your block) with the keyword argument, passing the result of this call to -objectAtIndex:

You probably want to combine -objectAtIndex: with -indexOfObjectPassingTest: ::

 NSString *keyword = /* whatever */; NSArray *array = self.myAppointment.OBSERVATIONS; NSUInteger idx = [array indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL *stop){ Observations *obs = (Observations*)obj; return [obs.TIME isEqualToString:keyword]; }]; if (idx != NSNotFound) Observations *obs = [array objectAtIndex:idx]; 
+25
source

This is an example that returns the row index in an array of strings. It can be adapted to any object.

 NSString* myString = @"stringToFind"; NSUInteger objectIndex = [myStringArray indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { return (*stop = ([obj isEqualToString:myString])); }]; 

To accurately answer the original question:

 NSString *keyword = @"myKeyword"; NSUInteger index = [self.myAppointment.OBSERVATIONS indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL *stop) { return (*stop = [(Observations*)obs.TIME isEqualToString:keyword]); }]; Observations *obs = (index!=NSNotFound) ? self.myAppointment.OBSERVATIONS[index] : NULL; 

But itโ€™s rather strange to compare something called TIME with a keyword ...;)

+4
source

No need to typedef or synthesize anything for your second example to work - just return the block from the method that will look like this:

 -(NSUInteger(^)(NSArray *, NSString *))findObs { return ^(NSArray *array, NSString *keyword) { for (NSUInteger i = 0; i < [array count]; i++) { Observations *obs = [array objectAtIndex:i]; if ([obs.TIME isEqualToString:keyword]) { return i; } } return NSNotFound; }; } Observations *obs = [self.myAppointment.OBSERVATIONS objectAtIndex:[self findObs](keyword)]; 

Here are some good reasons to define blocks as method return values โ€‹โ€‹rather than inline ones .

+3
source

Source: https://habr.com/ru/post/917791/


All Articles