[hmly]13. Please use @weakify and @strongify with caution

Source: Internet
Author: User

Objective

It is believed that most developers who have seen @weakify and @strongify will love the two macros. But many people only know the power of it, but do not realize the danger in a particular environment.

This article will tell the reader how to use these two macros correctly by means of code testing.

@weakify and @strongify

This article is intended to illustrate its dangers, so the two macros will not be fully explained.
If you are interested in it, please refer to other authors ' articles or view the source code yourself.

The two macros are defined as follows:

Extscope.h#l45-l47

#define weakify(...)     rac_keywordify     metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)


Extscope.h#l83-l88

#define strongify(...)     rac_keywordify     _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wshadow\"") metamacro_foreach(rac_strongify_,, __VA_ARGS__) _Pragma("clang diagnostic pop")

rac_keywordifythe definitions are as follows:
extscope.h#l114-l118

#if DEBUG#define rac_keywordify autoreleasepool {}#else#define rac_keywordify try {} @catch (...) {}#endif


Test

The following is an example code provided by the official.
The example code defines a block that is used to determine obj whether the incoming parameter is foo equal to, far any of the objects in it, and returns YES or NO .

ID foo =[[obj alloc]init];

ID far =[[obj Alloc]init];

@weakify (Foo,bar);

BOOL (^matchfooorbar) (id) = ^ bool (od obj) {

But Now,upon entry, "foo" and "bar" would stay alive until the block has

Finished excuting

@strongify (Foo,bar);

return [foo isequal:obj] | | [Bar Isequal:obj];

};

Test Code One

For the convenience of testing, here rac_keywordify is a rewrite of the definition.

{

#undef rac_keywordify

#define RAC_keywordify autoreleasepool { }

  

id foo = [[NSObject alloc] init];        id bar = [[NSObject alloc] init];        @weakify(foo, bar);        BOOL (^matchesFooOrBar)(id) = ^ BOOL (id obj){ @strongify(foo, bar); NSLog(@"%@,%@", foo, bar); }; }

}

It is believed that sharp-eyed's readers can see the difference between the above code at a glance.
Block missing return value

The following is Xcode. Xcode produces one Control reaches end of non-void block ?? Error prompt.

Test Code Two

For the convenience of testing, here rac_keywordify is a rewrite of the definition.

  {        #undef rac_keywordify        #define rac_keywordify try { } @catch(...) {}        id foo = [[NSObject alloc] init];        id bar = [[NSObject alloc] init];        @weakify(foo, bar); BOOL (^matchesFooOrBar)(id) = ^ BOOL (id obj){ @strongify(foo, bar); NSLog(@"%@,%@", foo, bar); }; }

By the know, Xcode loses the ability to error hints.

Problem analysis

In Release mode, it is rac_keywordify defined as #define rac_keywordify try { } @catch(...) {} , after being processed by the preprocessor, it is converted to the following code

  ID foo = [[NSObject alloc] init];ID bar = [[NSObject alloc] init];@try {}@catch (...) {} __attribute__ (Objc_ownership (Weak)) __typeof__ (foo) foo_weak_ = (foo); __ATTRIBUTE__ ((Objc_ownership (Weak)) __typeof__ (bar) Bar_weak_ = (bar);BOOL (^matchesfooorbar) (ID) = ^BOOL (ID obj) {@try {}@catch (...) {}# 99"/USERS/L/DOCUMENTS/WORKSPACE/.../APPDELEGATE.M"#pragma clang diagnostic push# " /users/l/documents/workspace/.../appdelegate.m"#pragma clang diagnostic ignored "-wshadow " # "/USERS/L/DOCUMENTS/WORKSPACE/.../APPDELEGATE.M" __attribute__ (objc_ownership (Strong)) __typeof__ ( Foo) foo = foo_weak_; __ATTRIBUTE__ ((Objc_ownership (Strong))) __typeof__ (bar) bar = Bar_weak_;  # " /users/l/documents/workspace/.../appdelegate.m"#pragma clang diagnostic pop# "/users/l/ DOCUMENTS/WORKSPACE/.../APPDELEGATE.M "; NSLog (@ "%@,%@", Foo, bar);};              

@try { } @catch(...) {}is added to the front of the equation.
In this case, Xcode's own error-hinting capability can be suppressed, as mentioned in the source notes.

Details about the choice of backing keyword:////theUseof @try/@catch/@finally can cause the compilerTo suppress//return-Type warnings.//theUseof @autoreleasepool {}IsNot optimized awayBy the compiler,//resultingIn superfluousCreationof Autorelease pools.////Since neitheroption is Perfect, and with no other alternatives, the//compromise  is to use @autorelease in DEBUG Builds to maintain compiler//analysis, and to use @try/@catch otherwise to avoid insertion Span class= "Hljs-keyword" >of unnecessary//autorelease pools.#if DEBUG#define rac_keywordify autoreleasepool {}#else# define rac_keywordify try {} @catch (...) {} #endif                

Many people have studied this part of the code, but most people have come to a similar conclusion.

The code at the beginning of this macro definition is less than @, so that weakify, strongify front must add @, of course, only this role. Then why do you judge debug here? I don't know, I don't think it's necessary to judge here.

The function of judgment is DEBUG that the normal development pattern is DEBUG carried out under the pattern. This preserves the ability of Xcode to prompt for errors.

Conclusion

Readers should recall that you can quickly determine whether you are developing in the DEBUG mode? If the answer is no, please use it carefully @weakify and @strongify .

Modify Development Mode

Click on the project name, in the popup box, clickEdit Scheme...


Paste_image.png

In Modal view, click the Build Configuration Radio box


Paste_image.png



[hmly]13. Please use @weakify and @strongify with caution

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.