Set a BOOL right after checking it - objective-c

I'm working through someone else's codebase and there are several lines like this:
if (self.aBooleanProperty) {
self.aBooleanProperty = YES;
// Do some stuff
}
Is there any point to setting it to YES right after checking it? Is there something I'm missing here?

if (self.aBooleanProperty) {
self.aBooleanProperty = YES;
// Do some stuff
}
In properly written code, you aren't missing anything and that setter line increases the billable lines of code by one with a no-op.
There are two reasons, though, that this could be done for misguided reasons.
As #HotLicks said, there may be side effects to the setter that might need to be triggered. But they should have been triggered on set unless the developer had the misguided notion of setting the ivar directly everywhere and then using the above to coalesce the cost of setting to one spot. But that'd be a remarkably fragile and silly thing to do.
The other reason is because, traditionally, Objective-C's BOOL is a glorified char. Only it isn't so glorified. Thus, comparing a BOOL to YES is actually dangerous because YES has an explicit value.
BOOL mmmmmK = 2; // this is valid
if (mmmmmK == YES) { /* this won't execute */ }
Sort of like when climbing a cliff and something starts falling, you don't yell "bottle", "shoe", "pebble", or "prosthetic limb", but you always yell ROCK.
So, maybe the developer was thinking of normalizing the affirmative with an explicit YES. Again, quite doubtful and, even if that is the case, then it should raise suspicion about the quality of the rest of the codebase.
Ouch.

This is difficult to tell without having more code. I think everybody will agree the code appears to be wrong, however, what we are seeing is an obj-c property - the previous programmer could do some "clever" thing, e.g. it's possible that the getter of aBooleanProperty sets itself to NO when you call it.
Before modifying the code, check the getters. This reminds me of schrödinbug

I think the person miswrote YES, instead should've written NO as it already is YES when it checked in the condition. Or otherwise there isne any point to that line.

if
self.aBooleanProperty = YES;
is included in the braces,it is not needed and if it is
self.aBooleanProperty = NO;
is included ,then it is logical

Related

How can I solve "Collection was mutated while being enumerated", #synrchonized, mutableCopy, or something else?

In Crashlytics, I'm seeing a crash that my users are experiencing quite infrequently. The offending code looks like this...
- (void)updateIsAnsweredField:(NSArray *)moduleItemsList
{
if (moduleItemsList && self.answeredItems && self.answeredItems.count > 0) {
for (ModuleItem * item in moduleItemsList) { // "Collection was mutated while being enumerated"
if ([item isKindOfClass:[ModuleItem class]] && [item shouldCheckIfAnswered]) {
item.answered = [self isAnsweredItem:item.moduleID];
}
}
}
}
The error given by Crashlytics can be seen in a comment in the code snippet above.
I assume there are a few ways to go about solving this.
1) wrap everything inside the function in #synchronized(moduleItemsList) {}. Is this the ideal way to solve? I've heard #synchronized is very slow and to avoid it when possible.
2) Create a copy a la NSMutableArray *copyModuleItemsList = [moduleItemsList mutableCopy];. Then enumerate that. Would this solve the issue? I would assume it would solve this particular issue, but there would be another problem no? That being... at the end when we go to assign our copy back to our original a la moduleItemsList = copyModuleItemsList;, moduleItemsList may have changed in the meantime on a different thread.
3) Trace the passed in :(NSArray *)moduleItemsList to whomever holds it as a property. Then overwrite the getter to use dispatch_sync, and the setter to use dispatch_barrier_async. However, there is no guarantee that the original array is a property of any class whose getter and setter can be overridden. And actually, none of this makes sense since we wouldn't be specifically changing that array would we?
I'm a bit confused. Can anyone assist in this matter? Is #1 the option I want?
EDIT: Adding more code
[item shouldCheckIFAnswered]:
This just checks a #property value that exists on the ModuleItem class. if self.moduleType == ModuleTypeSuchAndSuch
isAnsweredItem::
- (BOOL)isAnsweredItem:(NSString *)moduleID
{
if (!self.answeredItems) {
return NO;
}
return [self.answeredItems containsObject:moduleID];
}
From your post, it sounds like the moduleItemsList is getting modified in another thread. The "correct" way to fix this is going to depend on what the desired relationship between the state in the other thread and the state in this thread is.
If you use #synchronized(moduleItemsList) in both this code, and in the code that modifies the collection in the other thread, then when this code runs, it'll always have an "up to date" view of moduleItemsList.
If you copy the moduleItemsList into another object, then when this code runs, it might set the answered value on an item that's no longer in the moduleItemsList, or it might fail to set the answered flag on an item that was recently added to moduleItemsList.
In general, the #synchronized version is the easier way to get "correct" behavior. You'd only want to use copy if you're sure that it doesn't matter that the two threads may disagree about the current contents of moduleItemsList.
I've heard #synchronized is very slow and to avoid it when possible.
This is terrible advice, in general. #synchronized is just as slow as it needs to be to ensure consistent state between threads, and to provide a re-entrant lock. You don't want to just throw #synchronized around everything, willy-nilly, but it's a fine solution to synchronizing data access between threads - that's what it's for, after all.

Is a variable silently declared for you by the compiler/runtime when you don't declare one?

When I have a method with just a return statement and a value:
-(id)doSomethingCool
{
return [someArray objectAtIndex:2];
}
... is the compiler (or runtime) actually adding an intermediate variable behind the scenes:
-(id)doSomethingCool
{
id someObject = [someArray objectAtIndex:2];
return someObject;
}
I'm guessing at the assembly level it might be doing something like this?
I realize this is an obscure and probably performance-insignificant issue for 99% of applications, but I'm still curious what actually happens behind the curtains in Objective-C if anyone knows.
As an aside, is the only reason people do the first technique just for shorthand convenience, even if over tens of millions of iterations it would be no different had they done it the second way?
Conceptually, that's basically what happens. The value returned from the function is a temporary value. It's actually a copy of whatever value you're returning, which exists until the expression that the method call is used in finishes.
In practice, when you compile with optimizations turned on (in Release mode), the two examples you give will generate identical object code. The difference between the two is largely just down to style, though explicitly storing values in local variables can be useful in debugging.

Override setter in Objective-c. Why check is equal parameter

Often find custom setter sintaxis like this:
- (void)setParentCatalog:(Catalog *)parentCatalog {
if (_parentCatalog != parentCatalog) { //???
_parentCatalog = parentCatalog;
[self refresh];
}
}
Why i should check?
if (_parentCatalog != parentCatalog)
This checks if both _parentCatalog and parentCatalog are pointing to the same memory location.
If both are same object then no need to set the objectValue.
The reason for checking if the two are equal is to avoid executing code when it's not necessary. If the method is called very often, this could have a performance benefit. Under non-ARC, your code might look more like this:
- (void)setParentCatalog:(Catalog *)parentCatalog {
if (_parentCatalog != parentCatalog) {
[_parentCatalog release];
[parentCatalog retain];
_parentCatalog = parentCatalog;
[self refresh];
}
}
So, by checking that what you received is actually a new value, you avoid those retain and release calls happening (which are still there with ARC). You've also got [self refresh] in there, which probably doesn't need to happen unless the value has actually changed.
The idea here is that if the parameter passed in to the setter is the same object already stored in the property, then there is no need to call [self refresh] again.
A refresh method often reads in data, works on it and then re-displays it in the app's views. No need to do all this work again if the data in the property haven't really changed.
It's a decision that is use case dependant. The idea behind this guard is to prevent doing unnecessary work.
If you imagine that your [self refresh] kicked off a very expensive operation then you would be reluctant to do it every time. So if you only do it when the object actually changes you save yourself some work.
Of course this may well be the behaviour you are looking for in which case you would need to stick the [self refresh] call outside of the guard.
Like all code examples you find it's worth weighing up the trade offs of the implementation and then you can better decide what you need in your case.

Strict Type Checking in Objective-C via Macros

Occasionally, during development/debugging, I want to ensure that an object is of a certain type:
PageTopBottom *newPage = [notification object];
assert([newPage isKindOfClass:[PageTopBottom class]]);
which I've worked into this
#define assertType(_var_, _class_) assert([_var_ isKindOfClass:[_class_ class]])
and
PageTopBottom *newPage = (id)[notification object];
assertType(newPage, PageTopBottom);
but now I'd like to, if possible, just use
assertType(newPage)
Is it possible to get information about a variable's declared type from the variable?
I'm not positive that I'm framing the question correctly, but any answer that gets me to be able to assertType with one parameter would be great.
Is it possible to get information about a variable's declared type from the variable?
No. By the time the program is running, that information is lost. In your case, newPage is just a 32 or 64 bit number that points to a bit of memory that holds an Objective-C object.
I think your original unmacro'd version is the right thing to do here:
assert([newPage isKindOfClass:[PageTopBottom class]]);
That perfectly documents the assumption you are making i.e. that you assume newPage is an instance of PageTopBottom or one of its subclasses and it's completely clear to anybody who understands Objective-C. Your macro version slightly obfuscates that, in that somebody coming across it in the code might beleive it is asserting that newPage is a PageTopBottom and not one of its subclasses (you could change the name of the macro to prevent that, I suppose, but I just wouldn't bother).
Edit
What you could do is combine the declaration and assertion in one:
#define DECLARE_AND_ASSERT_IS_KIND_OF_CLASS(T, V, I) T* V = (T*)(I); assert([(V) isKindOfClass: [(T) class])
which would work like this:
DECLARE_AND_ASSERT_IS_KIND_OF_CLASS(PageTopBottom, newPage, [notification object]);
Hmm, with Objective-C++ there are two options:
Write a template function
template void assertType(T* obj) { ... }
For a pointer X* x, use NSClassFromString([NSString stringWithUTF8String:typeid(*x).name()]).
Without using C++, you might be able to use GCC extension typeof, but I'm not sure if [typeof(*x) class] is a legit operation...
The preprocessor only processes text; it has no knowledge of type, which is why it's sometimes considered 'dangerous'. The only way I could see doing it is wrapping the variable declarations in a macro, which I would strongly advise against, and probably wouldn't actually cut down on the code or complexity.
Also, shouldn't you check the type before casting?

Objective C - Which syntax?

What syntax do you think is better/more readable?
if(!myViewController.view.superview)
or:
if(myViewController.view.superview == nil)
Thanks!!
The two are very close, it comes down to personal taste or the conding standards of the project in question.
Saying !myViewController.view.superview meaning "no superview" is very clear.
Saying myViewController.view.superview == nil meaning superview is nil is also very clear.
I'd probably favor the former since if I was writing in English, I'd say:
if there is no superview then
I wouldn't say
if the superview is nothing then
But they are so close, and entirely equivalent, that it is hardly worth even being consistent with. Don't get me wrong, I'm all for consistency in general, it is just there really is no difference in readability between the two.
I use the second form because the intention is more clear that way.
Here is a link to Google's Objective C coding standards:
http://google-styleguide.googlecode.com/svn/trunk/objcguide.xml
They don't explicitly say which way they prefer but they do say to only use nil for logic checks, of which your example above would qualify.
Personally for a long time I used the latter expression, but reversed. Using "foo == nil" (or nil == foo, to avoid bugs caused by forgetting one '=') is more pedantic. Eventually you will get tired of typing it, and the first version is also immune to the accidental nil assignment bug.
It's good for new coders to be verbose in what they're coding, as it provides practise at forcing them to think about what's really going on, but later, of course switch to a version that is faster if it is equivalent.
If for some insane reason, nil pointers were not 0 anymore, but some other invalid value (there's entire gigantic regions of memory which are invalid as pointers), then using '!' wouldn't work anymore, but that will never happen (or if it did, they'd add support to the compiler to overload '!' so that it meant "not invalid" when used with an object pointer and would do the right thing anyway, or else the Objective-C developers of the world would go crazy).
The only subtle problem with this is that it can start to train you to confuse the value of C's boolean expressions with the values of other types, which they aren't the same thing. So, if you start to think a boolean expression is just a BOOL, say, you might assume that assigning any non-zero value to a BOOL variable will do what you want, but it won't. Since a BOOL is just a char (currently), if you do something like:
- (BOOL)checkFoo {
BOOL foo = [bar count]; // imagine count is > 255
if(foo)
[self doSomething];
return foo;
}
where implicitly casting 256 or higher to BOOL gets you zero (NO) by truncation, not YES, which is what you want, versus
- (BOOL)checkFoo {
BOOL foo = ([bar count] > 0);
if(foo)
[self doSomething];
return foo;
}
or
- (BOOL)checkFoo {
if([bar count]) {
[self doSomething];
return YES;
}
return NO;
}
All I'm saying is, make sure you understand the background and the subtleties.