@weakify如何在幕后工作?使用@weakify(self)的想法是让它作为一个简写:
__weak __typeof__(self) weakSelf = self;
注意:@weakify宏在这里定义.
我试图通过收集它使用的所有宏来了解它是如何工作的:
#define weakify(...) \ ext_keywordify \ metamacro_foreach_cxt(ext_weakify_,, __weak, __VA_ARGS__) #define ext_weakify_(INDEX, CONTEXT, VAR) \ CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR); #define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \ metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__) #define metamacro_argcount(...) \ metamacro_at(20, __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) #define metamacro_concat(A, B) \ metamacro_concat_(A, B) #define metamacro_concat_(A, B) A ## B #define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0) #define metamacro_at(N, ...) \ metamacro_concat(metamacro_at, N)(__VA_ARGS__) #define metamacro_head(...) \ metamacro_head_(__VA_ARGS__, 0) #define metamacro_head_(FIRST, ...) FIRST #define metamacro_at0(...) metamacro_head(__VA_ARGS__) #define metamacro_at1(_0, ...) metamacro_head(__VA_ARGS__) #define metamacro_at2(_0, _1, ...) metamacro_head(__VA_ARGS__) #define metamacro_at3(_0, _1, _2, ...) metamacro_head(__VA_ARGS__) #define metamacro_at4(_0, _1, _2, _3, ...) metamacro_head(__VA_ARGS__) #define metamacro_at5(_0, _1, _2, _3, _4, ...) metamacro_head(__VA_ARGS__) #define metamacro_at6(_0, _1, _2, _3, _4, _5, ...) metamacro_head(__VA_ARGS__) #define metamacro_at7(_0, _1, _2, _3, _4, _5, _6, ...) metamacro_head(__VA_ARGS__) #define metamacro_at8(_0, _1, _2, _3, _4, _5, _6, _7, ...) metamacro_head(__VA_ARGS__) #define metamacro_at9(_0, _1, _2, _3, _4, _5, _6, _7, _8, ...) metamacro_head(__VA_ARGS__) #define metamacro_at10(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, ...) metamacro_head(__VA_ARGS__) #define metamacro_at11(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) metamacro_head(__VA_ARGS__) #define metamacro_at12(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) metamacro_head(__VA_ARGS__) #define metamacro_at13(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, ...) metamacro_head(__VA_ARGS__) #define metamacro_at14(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, ...) metamacro_head(__VA_ARGS__) #define metamacro_at15(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, ...) metamacro_head(__VA_ARGS__) #define metamacro_at16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) metamacro_head(__VA_ARGS__) #define metamacro_at17(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, ...) metamacro_head(__VA_ARGS__) #define metamacro_at18(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, ...) metamacro_head(__VA_ARGS__) #define metamacro_at19(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, ...) metamacro_head(__VA_ARGS__) #define metamacro_at20(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, ...) metamacro_head(__VA_ARGS__) #if DEBUG #define ext_keywordify autoreleasepool {} #else #define ext_keywordify try {} @catch (...) {} #endif
我将上面的整个代码和下面的代码放在一个.c文件中:
@weakify(self)
并使用gcc -E test.c编译它.
我得到的输出是:
@try {} @catch (...) {} __attribute__((objc_gc(weak))) __typeof__(self) self_weak_ = (self);
题:
鉴于宏生成的输出是self_weak_.在正常使用的代码@weakify(个体经营),自仍然之后直接weakify引用()调用,如何使用自定转成微弱的自我,代码不使用self_weak_?
例如,我经常看到这个:
@weakify(self) [[self.obj doSomething];
self.obj如何使用弱自我?代码不应该是:
@weakify(self) [[self_weak_.obj doSomething];
Martin R.. 6
如果您使用转储clang预定义宏
clang -dM -E -x c /dev/null
然后你会发现
#define __weak __attribute__((objc_gc(weak)))
因此,如果您__weak
在源代码中写入,则会将其扩展为clang属性objc_gc(weak)
.换一种说法,
@try {} @catch (...) {} __attribute__((objc_gc(weak))) __typeof__(self) self_weak_ = (self);
相当于
@try {} @catch (...) {} __weak __typeof__(self) self_weak_ = (self);
现在@try {} @catch (...) {}
是一个无操作(定义一个看起来以@
字符开头的宏的技巧,比较我如何在登录Objective-C宏时使用商业广告?),所以剩下的就是
__weak __typeof__(self) self_weak_ = (self);
这是定义和初始化self_weak_
指向指向同一对象的弱变量的标准self
.
@weakify
意图与其对应物一起使用@strongify
,例如:
@weakify(self); // Expands to: // __weak __typeof__(self) self_weak_ = (self); void (^someClosure)(void) = ^void () { @strongify(self); // Expands to: // __strong __typeof__(self) self = (self_weak_); if (self) { [self doSomething]; [self doSomethingElse]; } };
在闭包内部,self
是一个局部变量,如果该对象仍然存在,则初始化为对象的强引用.如果对象在此期间已被释放(因为不再存在对它的强引用),self_weak_
则is nil
和local变量
self
也是nil
.
如果您使用转储clang预定义宏
clang -dM -E -x c /dev/null
然后你会发现
#define __weak __attribute__((objc_gc(weak)))
因此,如果您__weak
在源代码中写入,则会将其扩展为clang属性objc_gc(weak)
.换一种说法,
@try {} @catch (...) {} __attribute__((objc_gc(weak))) __typeof__(self) self_weak_ = (self);
相当于
@try {} @catch (...) {} __weak __typeof__(self) self_weak_ = (self);
现在@try {} @catch (...) {}
是一个无操作(定义一个看起来以@
字符开头的宏的技巧,比较我如何在登录Objective-C宏时使用商业广告?),所以剩下的就是
__weak __typeof__(self) self_weak_ = (self);
这是定义和初始化self_weak_
指向指向同一对象的弱变量的标准self
.
@weakify
意图与其对应物一起使用@strongify
,例如:
@weakify(self); // Expands to: // __weak __typeof__(self) self_weak_ = (self); void (^someClosure)(void) = ^void () { @strongify(self); // Expands to: // __strong __typeof__(self) self = (self_weak_); if (self) { [self doSomething]; [self doSomethingElse]; } };
在闭包内部,self
是一个局部变量,如果该对象仍然存在,则初始化为对象的强引用.如果对象在此期间已被释放(因为不再存在对它的强引用),self_weak_
则is nil
和local变量
self
也是nil
.