Ivan
Ivan

Reputation: 2332

Debugging incorrect usage of __weak variable in an Objective C++ class

I have the following -dealloc implementation in my Objective-C++ class (MyObjectiveCppClass):

- (void)dealloc {
  if (_my_iVar) {
    [_my_iVar doSomeSlowishCleanUp];
  }
}

Whenever this -dealloc method is called I get a bunch of warnings like:

objc[1254]: __weak variable at 0x1662a38c8 holds 0x19c70f408 instead of 0x160abe000. This is probably incorrect use of objc_storeWeak() and objc_loadWeak(). Break on objc_weak_error to debug.

When I break on objc_weak_error the stack looks like this:

#0  0x0000000182395330 in objc_weak_error ()
#1  0x00000001823959d0 in weak_clear_no_lock ()
#2  0x000000018239f1e8 in objc_object::clearDeallocating_slow() ()
#3  0x000000018238e074 in objc_destructInstance ()
#4  0x0000000182d25fac in -[NSObject(NSObject) __dealloc_zombie] ()
----> #5    0x00000001000a6c30 in -[MyObjectiveCppClass .cxx_destruct]
#6  0x0000000182382b54 in object_cxxDestructFromClass(objc_object*, objc_class*) ()
#7  0x000000018238e040 in objc_destructInstance ()
#8  0x0000000182d25fac in -[NSObject(NSObject) __dealloc_zombie] ()
---->    #9 0x00000001000a691c in -[MyObjectiveCppClass dealloc] 
#10 0x0000000100611bc4 in -[SomeViewB .cxx_destruct]
#11 0x0000000182382b54 in object_cxxDestructFromClass(objc_object*, objc_class*) ()
#12 0x000000018238e040 in objc_destructInstance ()
#13 0x0000000182d25fac in -[NSObject(NSObject) __dealloc_zombie] ()
#14 0x0000000188233a90 in -[UIResponder dealloc] ()
#15 0x0000000187e78b08 in -[UIView dealloc] ()
#16 0x0000000187f60700 in -[UIScrollView dealloc] ()
#17 0x0000000182c049b4 in -[__NSArrayM dealloc] ()
#18 0x00000001006495cc in -[SomeViewA .cxx_destruct]

Does anyone have any tips on figuring out how to fix these warnings?

Upvotes: 0

Views: 3776

Answers (2)

Jamshed Alam
Jamshed Alam

Reputation: 12844

May be it can help you, follow the steps:

  1. Remove ARC (-fobjc-arc) from your class. To do it, Go to Projects Settings->Build Phase->Compile Sources. Now select your class and remove -fobjc-arc. Now build it, if you have any autorelease, remove that from declaration in .m file. Suppose you have :

    UILabel *label = [[[UILabel alloc] initWithFrame:rect] autorelease];
    

Please do it like :

    UILabel *label = [[UILabel alloc] initWithFrame:rect];

Still you may have one issue like:

Cannot synthesize weak property in file using manual reference counting.

Don't worry for the issue.

If you don't have ARC, go to next step.

  1. After removing ARC, then go to project settings again. Go to Build Settings and search "Weak References in Manual Retain Release". The value is NO currently. Make it YES.

Now Clean, Build and Run.

Upvotes: 1

Ivan
Ivan

Reputation: 2332

It turns out that the _my_iVar object had an __unsafe_unretain reference to itself and passed it to some child objects of which one of assigned it to a weak local variable.

Upvotes: 1

Related Questions