iOS NSAssert 一不小心就循环引用了,注意

NSAssert 和 NSCAssert是我们经常使用的两个断言的宏定义

NSCAssert 的定义如下:

#define NSCAssert(condition, desc, ...) \
    do {                \
    __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \
    if (__builtin_expect(!(condition), 0)) {        \
            NSString *__assert_fn__ = [NSString stringWithUTF8String:__PRETTY_FUNCTION__]; \
            __assert_fn__ = __assert_fn__ ? __assert_fn__ : @""; \
            NSString *__assert_file__ = [NSString stringWithUTF8String:__FILE__]; \
            __assert_file__ = __assert_file__ ? __assert_file__ : @""; \
        [[NSAssertionHandler currentHandler] handleFailureInFunction:__assert_fn__ \
        file:__assert_file__ \
            lineNumber:__LINE__ description:(desc), ##__VA_ARGS__]; \
    }               \
        __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS \
    } while(0)

NSAssert 的定义如下:

#define NSAssert(condition, desc, ...)  \
    do {                \
    __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \
    if (__builtin_expect(!(condition), 0)) {        \
            NSString *__assert_file__ = [NSString stringWithUTF8String:__FILE__]; \
            __assert_file__ = __assert_file__ ? __assert_file__ : @""; \
        [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd \
        object:self file:__assert_file__ \
            lineNumber:__LINE__ description:(desc), ##__VA_ARGS__]; \
    }               \
        __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS \
    } while(0)

NSAssert,可以看到它的宏定义中出现了一个self。如果你在一个栈上的block回调中使用了NSAssert,无异于在里面直接用了self。循环引用了

例如:
下面的写法就存在内存泄露了

- (void)createUI
{
    ClickView *tempView = [[ClickView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    tempView.backgroundColor = [UIColor yellowColor];
    tempView.clickBlock = ^{
        
        NSAssert(条件判断, @"12345");
    };
    [self.view addSubview:tempView];
}

解决办法:

NSAssert 换成 NSCAssert

你可能感兴趣的:(iOS NSAssert 一不小心就循环引用了,注意)