3

I've a model class called PhotoItem. In which I have a BOOL property isSelected

@interface PhotoItem : NSObject

/*!
 * Indicates whether the photo is selected or not
 */
@property (nonatomic, assign) BOOL isSelected;

@end

I've an NSMutableArray which holds the object of this particular model. What I want to do is, in a particular event I want to set the bool value of all objects in the array to true or false. I can do that by iterating over the array and set the value.

Instead of that I tried using:

[_photoItemArray makeObjectsPerformSelector:@selector(setIsSelected:) withObject:[NSNumber numberWithBool:true]];

But I know it won't work and it didn't. Also I can't pass true or false as the param in that (since those are not object type). So for fixing this issue, I implemented a custom public method like:

/*!
 * Used for setting the photo selection status
 * @param selection : Indicates the selection status
 */
- (void)setItemSelection:(NSNumber *)selection
{
    _isSelected = [selection boolValue];
}

And calling it like:

[_photoItemArray makeObjectsPerformSelector:@selector(setItemSelection:) withObject:[NSNumber numberWithBool:true]];

It worked perfectly. But my question is, Is there any better way to achieve this without implementing a custom public method ?

3
  • Did you try with a "for cycle" on the objects array? Commented Oct 8, 2015 at 11:00
  • I think you are going to the right way. Commented Oct 8, 2015 at 11:01
  • Sidenote: The isSelected name for the property seems a bit odd. Apple uses a scheme where boolean properties are named with a simple adjective and have a setter name that uses the "is" prefix, like @property (getter=isSelected) BOOL selected;. This is even documented in the KVC guide explaining how keys are resolved. Commented Oct 8, 2015 at 11:55

1 Answer 1

8

Is there any better way to achieve this without implementing a custom public method?

This sounds like you are asking for opinion, so here is mine: Keep it simple.

for (PhotoItem *item in _photoItemArray)
    item.isSelected = YES;

Why obfuscate a simple thing with detours through obscure methods when you can write code that anybody will immediately understand?

Another way of doing the same thing would be:

[_photoItemArray setValue:@YES forKey:@"isSelected"];

This does not need the custom additional setter method because KVC does the unboxing for you.

But again I would vote against using such constructs. I think they are distracting from the simple meaning and confusing developers that come after you.

Sign up to request clarification or add additional context in comments.

4 Comments

+1 Worth emphasizing the use of YES here, which is not the same as true, and is one of the mistakes in the original code. (But agreed, a for loop is best.)
Using KVC seems about as clear as the for loop method to me, once you know that KVC methods on arrays forward the action to every item in the array. Learning this seems to me a bit like getting used to the trinary (?:)operator. It seems odd the first few times you encounter it, and then becomes natural. KVC does have some overhead, so the for..in loop is probably a little more performant, but the difference will be undetectable for all but the largest arrays.
@RobNapier: I didn't understand your comment. Can you please elaborate ? What is the mistake in original code with the use of true ? In my understanding both YES and true serve the same purpose (correct me if I'm wrong)
"Same purpose" sure in that they are both "true-like things." But they're different types. You can't substitute one for the other in general (and the bugs it can cause are truly glorious; I've had wonderful variables that were true, not-true, false, or not-false depending on how you tested them). In the majority of cases when dealing with ObjC, you want YES. It is very rare to use true (which is only in the language because it was inherited from recent updates to C).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.