Inconsistent object deallocation with ARC?

前端 未结 2 933
独厮守ぢ
独厮守ぢ 2021-02-06 06:08

I was playing around with memory (de)allocation stuff on a simple command line app for Mac OSX 10.7 built using Xcode Version 4.2.1 with ARC enabled, and the default build setti

相关标签:
2条回答
  • 2021-02-06 06:30

    If you disassemble A.R.C.-produced code, every access to a weak variable is wrapped in a call to this function:

    id objc_loadWeak(id *location)
    {
        return objc_autorelease(objc_loadWeakRetained(location));
    }
    

    This checks if the object has already been dealloced, and if not, retains and autoreleases it, for extra safety against premature deallocs.

    Therefore in your third example, the early calls to method on weakRef are causing its retain count to be increased, so nilling your pointers doesn't cause it to be dealloced.

    0 讨论(0)
  • 2021-02-06 06:50

    This does seem strange. You're right (in your comments) about the 2nd bit of code just being because the memory hasn't been re-used yet. But the 3rd bit of code is stranger. Here is a more simplified test case which shows this strange problem:

    #import <Foundation/Foundation.h>
    
    @interface SomeClass : NSObject 
    @end
    
    @implementation SomeClass
    - (void)foo {
    }
    @end
    
    int main (int argc, const char * argv[]) {
        @autoreleasepool {
            SomeClass *objPtr1 = [[SomeClass alloc] init];
            __weak SomeClass *weakRef = objPtr1;
    
    //        [weakRef foo];
            [weakRef foo];
    
            objPtr1 = nil;
    
            NSLog(@"%p", weakRef);
    
            return 0;
        }
    }
    

    With that line commented out the output is:

    $ clang -fobjc-arc -framework Foundation test.m -o test -O3 && ./test
    2012-02-12 00:39:42.769 test[6684:707] 0x0
    

    With that line uncommented out the output is:

    $ clang -fobjc-arc -framework Foundation test.m -o test -O3 && ./test
    2012-02-12 00:42:04.346 test[6688:707] 0x100f13f50
    

    This seems deeply odd and looks entirely like a bug to me. I don't actually know what the answer is but thought I'd post this as an answer to get the ball rolling on figuring out what's going on.

    Update:

    If you build this at O0 then it seems that weakRef is zeroed only if there are no calls to foo. A single call to foo will mean that it won't get zeroed.

    0 讨论(0)
提交回复
热议问题