In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
In this article Xiaobian for you to introduce in detail "iOS block value capture and pointer capture method", the content is detailed, the steps are clear, the details are handled properly, I hope this "iOS block value capture and pointer capture method" article can help you solve your doubts, the following follow the editor's ideas slowly in-depth, together to learn new knowledge.
Pointer and pointer variable
Popular understanding:
Pointers: memory address
Pointer variable: the variable that stores the memory address
Pointer to a pointer variable: memory address of the pointer variable itself
Person * p = [Person new]
The isa on the right is: memory address of object-pointer
P is: pointer variable
The isa on the left is: memory address of pointer variable-pointer of pointer variable
Block captures variable mode
There are two forms of local variable capture: 1, value capture (local automatic variable) 2, pointer capture (local static variable); global variable does not need to be captured and can be accessed directly.
The result of clang-rewrite-objc * * .m-o * * .cpp converted to C++ code in different scenarios is as follows (see the conclusion below if the code is too long and you don't want to see it)
Value capture
Capture of pointer variables
A new pointer variable is used internally in block to receive the original pointer variable. After receiving, the value stored in the two pointer variables is the memory address of the object, so it can also be said to be the capture of the value.
Local automatic variables:
Int main (int argc, const char * argv []) {@ autoreleasepool {Person * p = [Person new]; void (^ block) (void) = ^ {NSLog (@ "% @", p);}; block ();} return 0;} struct Person_IMPL {struct NSObject_IMPL NSObject_IVARS;}; struct _ _ main_block_impl_0 {struct _ block_impl impl Struct _ _ main_block_desc_0* Desc; Person * p; _ _ main_block_impl_0 (void * fp, struct _ main_block_desc_0* desc, Person * _ p, int flags=0): P (_ p) {impl.isa = & _ NSConcreteStackBlock; impl.Flags = flags; impl.FuncPtr = fp; Desc = desc;}} Static void _ main_block_func_0 (struct _ main_block_impl_0 * _ cself) {Person * p = _ _ cself- > p; / / bound by copy NSLog ((NSString *) & _ _ NSConstantStringImpl__var_folders_7w_wgxxl_655s9g6tms_7z44s6w0000gn_T_main_f76e59_mi_0,p) } static void _ main_block_copy_0 (struct _ main_block_impl_0*dst, struct _ main_block_impl_0*src) {_ Block_object_assign ((void*) & dst- > p, (void*) src- > p, 3/*BLOCK_FIELD_IS_OBJECT*/) } static void _ main_block_dispose_0 (struct _ main_block_impl_0*src) {_ Block_object_dispose ((void*) src- > p, 3/*BLOCK_FIELD_IS_OBJECT*/);} static struct _ main_block_desc_0 {size_t reserved; size_t Block_size; void (* copy) (struct _ _ main_block_impl_0*, struct _ _ main_block_impl_0*) Void (* dispose) (struct _ _ main_block_impl_0*);} _ _ main_block_desc_0_DATA = {0, sizeof (struct _ _ main_block_impl_0), _ _ main_block_copy_0, _ _ main_block_dispose_0}; int main (int argc, const char * argv []) {/ * @ autoreleasepool * / {_ _ AtAutoreleasePool _ autoreleasepool Person * p = (Person * (*) (id, SEL) (void *) objc_msgSend) ((id) objc_getClass ("Person"), sel_registerName ("new")); void (* block) (void) = ((void (*) ()) & _ main_block_impl_0 ((void *) _ main_block_func_0, & _ main_block_desc_0_DATA, p, 570425344) ((void (*) (_ _ block_impl *)) ((_ _ block_impl *) block)-> FuncPtr) ((_ _ block_impl *) block);} return 0;}
Code analysis, a pointer variable is created in the generated _ _ main_block_impl_0 structure, and the pointer variable p is also passed in when the _ _ main_block_impl_0 in the main function is initialized. Therefore, the way block captures local automatic variables is the capture of pointer variables, that is, value capture.
Pointer capture
Capture of the pointer of the pointer variable itself
Inside block, a new pointer is used to receive (point to) the address of the original pointer variable itself.
Local static variables:
Int main (int argc, const char * argv []) {@ autoreleasepool {static Person * p = nil; p = [Person new]; void (^ block) (void) = ^ {NSLog (@ "% @", p);}; block ();} return 0;} struct Person_IMPL {struct NSObject_IMPL NSObject_IVARS;} Struct _ _ main_block_impl_0 {struct _ block_impl impl; struct _ main_block_desc_0* Desc; Person * * p; _ _ main_block_impl_0 (void * fp, struct _ main_block_desc_0* desc, Person * * _ p, int flags=0): P (_ p) {impl.isa = & _ NSConcreteStackBlock; impl.Flags = flags; impl.FuncPtr = fp; Desc = desc;}} Static void _ _ main_block_func_0 (struct _ main_block_impl_0 * _ cself) {Person * * p = _ _ cself- > p; / / bound by copy NSLog ((NSString *) & _ _ NSConstantStringImpl__var_folders_7w_wgxxl_655s9g6tms_7z44s6w0000gn_T_main_bd39c2_mi_0, (* p)) } static void _ main_block_copy_0 (struct _ main_block_impl_0*dst, struct _ main_block_impl_0*src) {_ Block_object_assign ((void*) & dst- > p, (void*) src- > p, 3/*BLOCK_FIELD_IS_OBJECT*/) } static void _ main_block_dispose_0 (struct _ main_block_impl_0*src) {_ Block_object_dispose ((void*) src- > p, 3/*BLOCK_FIELD_IS_OBJECT*/);} static struct _ main_block_desc_0 {size_t reserved; size_t Block_size; void (* copy) (struct _ _ main_block_impl_0*, struct _ _ main_block_impl_0*) Void (* dispose) (struct _ _ main_block_impl_0*);} _ main_block_desc_0_DATA = {0, sizeof (struct _ _ main_block_impl_0), _ _ main_block_copy_0, _ _ main_block_dispose_0}; int main (int argc, const char * argv []) {/ * @ autoreleasepool * / {_ _ AtAutoreleasePool _ autoreleasepool; static Person * p = _ _ null P = ((Person * (*) (id, SEL)) (void *) objc_msgSend) ((id) objc_getClass ("Person"), sel_registerName ("new")); void (* block) (void) = (void (*) ()) & _ main_block_impl_0 ((void *) _ main_block_func_0, & _ main_block_desc_0_DATA, & p, 570425344) ((void (*) (_ _ block_impl *)) ((_ _ block_impl *) block)-> FuncPtr) ((_ _ block_impl *) block);} return 0;}
Code analysis, a pointer is created in the generated _ _ main_block_impl_0 structure * the _ _ main_block_impl_0 in the pforce main function is initialized, passing in the address of the pointer variable p & p. Therefore, the way block captures local static variables is to capture the address of the pointer variable itself, that is, pointer capture.
_ _ block modified variable int main (int argc, const char * argv []) {@ autoreleasepool {_ block Person * p = [Person new]; void (^ block) (void) = ^ {NSLog (@% @ ", p);}; block ();} return 0;} struct Person_IMPL {struct NSObject_IMPL NSObject_IVARS;} Struct _ Block_byref_p_0 {void* _ isa;__Block_byref_p_0 * _ forwarding; int _ flags; int _ size; void (* _ Block_byref_id_object_copy) (void*, void*); void (* _ Block_byref_id_object_dispose) (void*); Person * p;}; struct _ main_block_impl_0 {struct _ block_impl impl; struct _ main_block_desc_0* Desc _ _ Block_byref_p_0 * p; / / byref_ _ main_block_impl_0 (void * fp, struct _ _ main_block_desc_0 * desc, _ _ Block_byref_p_0 * _ p, int flags=0): P (_ p-> _ _ forwarding) {impl.isa = & _ NSConcreteStackBlock; impl.Flags = flags; impl.FuncPtr = fp; Desc = desc;}} Static void _ main_block_func_0 (struct _ main_block_impl_0 * _ cself) {_ _ Block_byref_p_0 * p = _ _ cself- > p; / / bound byref NSLog ((NSString *) & _ _ NSConstantStringImpl__var_folders_7w_wgxxl_655s9g6tms_7z44s6w0000gn_T_main_6c171f_mi_0, (p-> _ _ forwarding- > p)) } static void _ main_block_copy_0 (struct _ main_block_impl_0*dst, struct _ main_block_impl_0*src) {_ Block_object_assign ((void*) & dst- > p, (void*) src- > p, 8/*BLOCK_FIELD_IS_BYREF*/) } static void _ main_block_dispose_0 (struct _ main_block_impl_0*src) {_ Block_object_dispose ((void*) src- > p, 8/*BLOCK_FIELD_IS_BYREF*/);} static struct _ main_block_desc_0 {size_t reserved; size_t Block_size; void (* copy) (struct _ _ main_block_impl_0*, struct _ _ main_block_impl_0*) Void (* dispose) (struct _ _ main_block_impl_0*);} _ _ main_block_desc_0_DATA = {0, sizeof (struct _ _ main_block_impl_0), _ _ main_block_copy_0, _ _ main_block_dispose_0}; int main (int argc, const char * argv []) {/ * @ autoreleasepool * / {_ _ AtAutoreleasePool _ autoreleasepool _ _ attribute__ ((_ _ blocks__ (byref) _ Block_byref_p_0 p = {(void*) 0, (_ _ Block_byref_p_0 *) & p, 33554432, sizeof (_ _ Block_byref_p_0), _ _ Block_byref_id_object_copy_131, _ _ Block_byref_id_object_dispose_131, ((Person * (*) (id) SEL)) (void *) objc_msgSend) ((id) objc_getClass ("Person"), sel_registerName ("new"))} Void (* block) (void) = ((void (*) ()) & _ _ main_block_impl_0 ((void *) _ main_block_func_0, & _ _ main_block_desc_0_DATA, (_ _ Block_byref_p_0 *) & p, 570425344)); ((void (*) (_ _ block_impl *)) ((_ _ block_impl *) block)-> FuncPtr) ((_ _ block_impl *) block) } return 0;}
Code analysis, the pointer variable p modified with _ _ block, is converted to the structure of _ _ Block_byref_p_0, which holds p in the body. When initializing _ _ main_block_impl_ 0 in the main function, the address of _ _ Block_byref_p_0 is passed. When p is accessed, it is accessed through the _ _ forwarding pointer of _ _ Block_byref_p_0. In fact, it is equivalent to capturing the pointer of _ _ Block_byref_p_0 inside block and accessing the p held by _ _ Block_byref_p_0 through the pointer. So the variable modified by _ _ block is essentially a kind of pointer capture, but not directly capturing the address of the pointer variable p.
Can value capture be reassigned? When copying a value, if a pointer variable of the same name within block performs a reassignment operation, it is equivalent to making the internal pointer variable point to a new object, and any operation on this object has nothing to do with the original object pointed to by the original pointer variable, so it cannot be reassigned.
Can pointer capture be reassigned? Block assigns the pointer of the pointer variable outside the block to a new pointer, and the pointers inside and outside the block point to the same pointer variable. If you do an assignment, you are operating on the same pointer variable, so you can reassign it.
Read this, the "iOS block value capture and pointer capture method" article has been introduced, want to master the knowledge of this article also need to practice and use to understand, if you want to know more about the article, welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.