1
votes

I've just finished debugging an issue where an iOS Google Map (GMSMapView) showed on some devices and in some iOS version simulators, but not others. It was odd that it broke on a 32-bit iOS 7 device and 64-bit iOS 7 simulator, but not other combinations, indicating it wasn't an iOS version specific or 64-bit specific, but something else. Anyway, the fact that it was a GMSMapView and had strange variation in behaviour across devices/simulators may be an aside, but perhaps it's related to the question and someone can explain it in the context.

Basically, I had a property something like:

@property (weak, nonatomic)GMSMapView *myMap;

And had been assigning it in viewDidLoad with something like:

self.myMap = [GMSMapView mapWithFrame:CGRectMake(0.0, 0.0, self.view.bounds.size.width, self.view.bounds.size.height) camera:self.myPosition];

As previously mentioned, this worked on some device/simulator combos but not others, which was odd. Changing myMap from weak to strong made it work on all combinations.

I experienced some strange behavior during debugging though which made this difficult to establish. I started by putting a breakpoint on the line that assigned a value to self.myMap (listed above) to check the line was being hit. Now, when debugging, it hit this breakpoint as expected. What was strange though is that the following behavior differed depending on whether I hit Continue program execution or Step over. If I hit Continue program execution, self.myMap was still nil a few lines later where I had another breakpoint. If I hit Step over and then immediately after hit Continue program execution, self.map was assigned properly when the breakpoint a few lines later was hit.

So, an execution of the same program resulted in a different assignment of the weak property self.myMap based solely on whether or not I hit Step over after hitting the first breakpoint. So my primary question is:

Why would a different progression through the debugger cause a different result?

And I guess this may or may not be somehow related to the weak variable working on some device/simulator combos but not others. For reference, XCode 5.1.

1
It's not really an answer to your question but you should rather use the static analyzer to find this kind of compilation time issues, not a step by step debuging.Marcio
I think this is due to the very fact of using a weak variable the way you're using it. Normally when using an object being pointed to by a weak variable, you first assign it to a local strong variable to ensure the object is valid throughout the execution, and when the local variable goes out of scope you still have the weak class variableMerlevede
Your original bug and this symptom are both most likely due to timing issues. When you step through code you get different timing between threads (with resulting possible differences in access order) than when you let it run.Hot Licks
Also note that you can get different timing between debug and release builds. In particular, with a release build operations are apt to occur in a different order from what you expect.Hot Licks

1 Answers

1
votes

I've had issues like this before between release and debug builds. There is some difference in timing between when weak references are nilled out, presumably because the debugger is holding on to references for some reason. I don't know the details of how ARC is implemented but it seems to be a fairly consistent pattern.

Directly assigning a newly created object to a weak reference is wrong - under the rules of ARC it would be instantly deallocated and nilled out, because nothing else has a strong reference to it.

This is the main reason I don't like to have view or IBOutlet properties set to weak - there is no need, since views don't get unloaded any more, and it just leads to subtle bugs like this.