在Objective-C块中使用typeof(self)来声明一个强引用

时间:2014-10-07 22:52:45

标签: objective-c objective-c-blocks

使用weakSelf/strongSelf模式避免在块中创建保留周期,此代码非常常见:

typeof(self) __weak weakSelf = self;
void (^block)() = ^{
    typeof(weakSelf) strongSelf = weakSelf;
    // ...more code...
};

问题是,是否将第二个typeof(weakSelf)更改为typeof(self)会导致self在块中被捕获?

例如:

typeof(self) __weak weakSelf = self;
void (^block)() = ^{
    typeof(self) strongSelf = weakSelf; // does using typeof(self) here end up capturing self?
    // ...more code...
};

如果没有捕捉到自我,是否有理由偏好这种或那种方式?

2 个答案:

答案 0 :(得分:8)

不应该。如果是,那就是编译器错误。

typeof表达式实际上并未引用变量self或其值。它严格地是对表达式的引用,而不是它的价值。表达式严格来说是一个编译时构造,它不会存在于编译代码中。

我个人更喜欢typeof(self),但我认为不太喜欢这样或那样的强烈争论。

答案 1 :(得分:5)

没有。 Ken说#import <Foundation/Foundation.h> int main(int argc, char *argv[]) { @autoreleasepool { NSObject *o = [NSObject new]; __weak typeof(o) weakO = o; void(^b)() = ^{ __strong typeof(o) strongO = weakO; NSLog(@"o: %@", strongO); }; o = nil; b(); /* outputs: 2015-05-15 16:52:09.225 Untitled[28092:2051417] o: (null) */ } } 是编译时表达式的确适用。

这里还有一段证明它的代码:

b1.setOnClickListener(new Button.OnClickListener(){

        @Override
        public void onClick(View v) {

             setContentView(R.layout.activity_main_activity2); 
             button = (Button) findViewById(R.id.button21);
             button.setOnClickListener(new Button.OnClickListener(){


        @Override
        public void onClick(View v) {
                             Toast.makeText(getBaseContext(),"Working",Toast.LENGTH_SHORT).show();         

}
    });              
        }
    });


or you can goto your other activity 

b1.setOnClickListener(new Button.OnClickListener(){

    @Override
    public void onClick(View v) {
       // setContentView(R.layout.activity_main_activity2); remove
          startActivity(new Intent(MainActivity.this,MainActivity2.class));
    }

});