autoreleasing的用法介绍:
在c/c++,objective-c内存管理中有一条是:谁分配谁释放。 __autoreleasing则可以使对像延迟释放。比如你想传一个未初始化地对像引用到一个方法当中,在此方法中实始化此对像,那么这种情况将是__autoreleasing表演的时候。看个示例:
-
- (void) generateErrorInVariable:(__autoreleasing NSError **)paramError{ NSArray *objects = [[NSArray alloc] initWithObjects:@"A simple error", nil]; NSArray *keys = [[NSArray alloc] initWithObjects:NSLocalizedDescriptionKey, nil]; NSDictionary *errorDictionary
= [[NSDictionary alloc] initWithObjects:objects forKeys:keys]; *paramError = [[NSError alloc] initWithDomain:@"MyApp" code:1 userInfo:errorDictionary]; } -(void)test { NSError *error = nil; [self generateErrorInVariable:&error]; NSLog(@"Error = %@", error);
}
复制代码
被编译器翻译后就变为:
-
-(void)test { NSError *error = nil; NSError * __autoreleasing tmp = error; [self generateErrorInVariable:&tmp]; error = tmp; NSLog(@"Error = %@", error); }
复制代码
这样即便在函数内部申请的空间,在函数外部也可以使用,同样也适合谁分配谁释放的原则。
同样下面的代码也是类似原因, 只不过在没有开启ARC的情况下适用:
-
-(NSString *)stringTest { NSString *retStr = [NSString stringWithString:@"test"]; return [[retStr retain] autorelease]; }
复制代码
开启ARC后,应改为:经过测试下面这种方法是可行的,不过都不建意这样写代码, __autoreleasing官网的例子是用在传引用参数当中(像上面那个NSError)。所以最好不要像下面这样用
-
-(NSString *)stringTest { __autoreleasing NSString *retStr = [NSString alloc] initWithString:@"test"]; return retStr; }
-
- (NSString *)stringTest __attribute__((ns_returns_autoreleased)){ NSString *retStr = [NSString alloc] initWithString:@"test"];return retStr;}
复制代码
与上面功能相似。返回一个autorelease。
关于methord family, 如果方法名是以alloc, init, copy, mutablecopy,new字符开头的,那么它们的返回值会被retain的,其它的默认就是autorelease返回的。下面介绍一下返回值的例子:
-
- (id) foo __attribute((ns_returns_retained)); //返回值retain +1, init,new,alloc,copy,mutablecopy default are this - (id) foo __attribute((ns_returns_not_retained)); //返回指针弱引用, - (id) foo __attribute((ns_returns_autoreleased)); //返回autorlease, except default,
are this
复制代码
init开头的方法有一个规定,一定要返回id或父类,子类的指针,不然要有warning.
这儿是原话:
-
init methods must be instance methods and must return an Objective-C pointer type. Additionally, a program is ill-formed if it declares or contains a call to an init method whose return type is neither id nor a pointer to a super-class or sub-class of the
declaring class (if the method was declared on a class) or the static receiver type of the call (if it was declared on a protocol).
复制代码
当然你也可以打破这个规定,如果你这样声明方法:
-
- (void)initStr __attribute__((objc_method_family(none)));
复制代码
那么就是正确的。
原文地址:https://www.cnblogs.com/zsw-1993/p/4879685.html