Objective-C - weak property - auto-genase-generators (automatic reference counting)

I have a doubt about the weak property in ARC (auto-advertisement counting)

My understanding (correct me if I am wrong):

weak property behaves similar to the assign property, except that when the instance that the property indicated was destroyed, ivar is set to zero.

Question:

  • I just feel that the receiver of the weak property is saving and auto-implementing. Shouldn't this behave like the getter of the assign property, where the getter doesnโ€™t save auto-advertisement as well? (Pls refers to the program)

Program:

I have given below a program with the actual result and the expected output.

Note When I change the property from weak to assign , my expected result is fulfilled

 #import<Foundation/Foundation.h> @interface A : NSObject - (void) dealloc; @end @implementation A - (void) dealloc { printf("\tinstance of A deallocated = %p\n", self); } @end @interface B : NSObject @property (weak) A* xa1; - (void) dealloc; @end @implementation B @synthesize xa1; - (void) dealloc { printf("\tinstance of B deallocated = %p\n", self); } @end int main() { B* b1 = [[B alloc] init]; @autoreleasepool //autoreleasepool 1 { { //block 1 A* a1 = [[A alloc] init]; printf("\ta1 = %p\n", a1); b1.xa1 = a1; A* a3 = b1.xa1; printf("--- end of block 1\n"); } //at this point i expected instance pointed by a1 to be destroyed printf("--- end of autoreleasepool 1\n"); } printf("---- end of main\n"); return(0); } 

Actual output:

  a1 = 0x10d713f50 --- end of block 1 --- end of autoreleasepool 1 instance of A deallocated = 0x10d713f50 ---- end of main instance of B deallocated = 0x10d713d30 

My expected result:

  a1 = 0x10d713f50 --- end of block 1 instance of A deallocated = 0x10d713f50 --- end of autoreleasepool 1 ---- end of main instance of B deallocated = 0x10d713d30 

thanks

+4
source share
2 answers

The supply of weak to a property implies __weak ownership of ivar, i.e. this is just an instruction for @synthesize .

According to http://clang.llvm.org/docs/AutomaticReferenceCounting.html ยง4.2, reading the __weak variable requires saving the object (and freeing after, of course):

Reading occurs when the lvalue-to-rval conversion is performed on the lvalue object.

  • For __weak objects, the current pointer is stored and then released at the end of the current full expression. This should be done atomically with respect to assignments and the final version of the clause.
  • For all other objects, lvalue is loaded with primitive semantics.

It does not say why, but think about what happens if the object you received from the __weak variable dies before you even start using it. The goal of a weak pointer is to make sure that you have either nil or a valid object with a known lifetime, so reading its value implies storing a comma (and then the getter property returns it auto-implemented).

This is not unique to Obj-C, it is a common idiom for all weak pointer implementations (both recalculated and garbage collected). Weak pointers cannot give the value of a pointer directly; they must create a strong pointer to a hold object to ensure that it does not die before the caller even starts using it. In Obj-C, it saves-autorelease; in C ++, weak_ptr creates shared_ptr firstly, in garbage-collected environments, a strong reference is returned, and the lifetime of the object is extended silently.

+4
source

Getter for x1 looks like this:

 function -[B xa1] { var_8 = rdi; var_0 = rsi; rdi = objc_loadWeakRetained(var_8 + *_OBJC_IVAR_$_B.xa1); rax = [rdi autorelease]; return rax; } 

So, when you get the property in

 A* a3 = b1.xa1; 

a1 == b1.xa1 receive an autodetection call and save it autoreleasepool

0
source

Source: https://habr.com/ru/post/1381440/


All Articles