关于 __autoreleasing

今天早晨为了重构一下工程的model部分,就想用MTL来重构它。

然后Github的Readme上有部分地方的理解不太懂,就去看源码。结果看了两行发现了一个奇怪的东西。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (instancetype)initWithDictionary:(NSDictionary *)dictionary error:(NSError **)error {
  self = [self init];
  if (self == nil) return nil;

  for (NSString *key in dictionary) {
      // Mark this as being autoreleased, because validateValue may return
      // a new object to be stored in this variable (and we don't want ARC to
      // double-free or leak the old or new values).
      __autoreleasing id value = [dictionary objectForKey:key];
  
      if ([value isEqual:NSNull.null]) value = nil;

      BOOL success = MTLValidateAndSetValue(self, key, value, YES, error);
      if (!success) return nil;
  }

  return self;
}

作为一个没有好好读过ARC文献的人来说,见到__autoreleasing 这个标识,感觉不明觉厉。

拉着Lancy讨论半天,越讨论越歪,就去看伟大的Stackoverflow。

中间讨论出来的歪理,就不说了,说多了可能会误导,还是忘掉吧。

直接说结论:

__autoreleasing 这个东西一般出现在NSError 这种地方,即要传入的是指针的指针的地方。

例如:

1
2
3
4
5
NSError *error;
BOOL OK = [myObject performOperationWithError:&error];
if (!OK) {
    // Report the error.
    // ...

这个时候,如果没有添加 __autorelease 就会被编译器解析成:

1
2
3
4
5
6
7
8
NSError * __strong error;
NSError * __autoreleasing tmp = error;
BOOL OK = [myObject performOperationWithError:&tmp];
error = tmp;
if (!OK) {
    // Report the error.
    // ...

这个时候你会发现,error 被引入了一个中间变量,浪费了4字节的空间。

如果添加了__autorelease 就不会被这么解析了。

未解之谜

为何要用autorelease呢?!

不知道!!!!!

钻研了一上午 还是不知道,因为什么导致内存泄露么?也许吧。

ARC, iOS

Comments