获取块的弱类型的宏

时间:2014-01-20 10:29:34

标签: ios objective-c macos objective-c-blocks weak-references

我想知道创建一个类型__weak版本所需的所有样板需要在块内使用以避免保留周期。 我使用的经典方式是:

__weak typeof(self) weakSelf = self;

我的直接解决方案是定义一个新功能,如:

#define weakTypeof(type) __weak typeof(type)

好的,这不是一个很大的改进,但是我们必须在任何地方输入__weak,因为:

weakTypeof(self) weakSelf = self;

我有什么理由不这样做吗? 有更好/更有效的方法吗?

3 个答案:

答案 0 :(得分:4)

我只是在Xcode中使用代码片段 http://nshipster.com/xcode-snippets/

当我将weakSelf键入您粘贴的代码时,我设置了一个,这是一个真正的节省时间。

答案 1 :(得分:3)

我认为它可能也很容易写:

__weak typeof(self) weakSelf = self;

它是一行样板代码,可以让任何阅读代码的人都可以立即理解。如果你使用片段,那么写作几乎不需要花费任何时间。

如果您使用宏,最终会得到与原始语句几乎相同长度的代码,这样您就不会花费太多时间而且您已经牺牲了可读性,因为您仍然需要知道什么是宏确实。

所以,在我看来(你知道我和我的意见一样),这不是你需要担心的事情。通过尝试简化它,你什么都得不到。

修改

添加到我的断言中。我确定你有很多行:

@property (strong, nonatomic) UIView *someSubview;
@property (weak, nonatomic) id<SomeDelegateProtocol> delegate;
@property (copy, nonatomic) NSString *someString;

如果您认为拥有宏的良好想法,那么您可以写下:

propStrong UIView *someSubview;
propWeak id<SomeDelegateProtocol> delegate;
propCopy NSString *someString;

然后继续为您的weakSelf声明实现一个宏。

但如果您认为原始版本只是一个常见的样板,如果写的时间稍长可以完全阅读,并且每个人一眼就能理解,那么我不认为您需要担心未装饰的弱自我声明。

答案 2 :(得分:1)

虽然我同意@abizern回答关于代码的可读性胜过写作速度这一事实我从这个project找到了一个有趣的方法,并且为了论证我认为发布它是一个好主意。
作者在这里创建一个宏来制作变量的弱副本,如@weakify(<a_variable>),然后使用@weakify(<a_variable>)在块内引用它。 该项目也包含在ReactiveCocoa中并广泛使用。

源文件中有很多宏,主要是为了处理你可以用多个变量作为参数实际调用@weakify()@strongify()的事实,但我设法减少所有代码这个例子在这里:

#define metamacro_concat(A, B) A ## B
#define weakify(VAR) \
  autoreleasepool {} \
  __weak __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR)
#define strongify(VAR) \
  autoreleasepool {} \
  _Pragma("clang diagnostic push") \
  _Pragma("clang diagnostic ignored \"-Wshadow\"") \
  __strong __typeof__(VAR) VAR = metamacro_concat(VAR, _weak_)\
  _Pragma("clang diagnostic pop")

...

NSString *string = @"test";

@weakify(string);

[anyObject asyncBlock:^{

    @strongify(string);
    NSLog(@"%@", string);
}];