Хороший вопрос с неочевидным ответом.
Это связано с классификаторами собственности , связанным с переменными. При объявлении:
NSView *view;
это сокращение для:
NSView __strong * view;
т.е. ссылка прочно удерживаются переменной view
.
Однако при объявлении:
-(void)test:(UIView **)view
это сокращение для:
-(void)test:(UIView * __autoreleasing *)view
view
здесь имеет тип указатель на переменную указателя типа __autoreleasing к UIView
.
Причина этой разницы, __strong
против __autoreleasing
, из-за какого вызова по обратной записи Apple, термина и объясняется в Variable Qualifiers in Apple's "Transitioning to ARC Release Notes" и в Ownership qualification in CLANG Documentation: Automatic Reference Counting. Также объясняются вопросы SO Handling Pointer-to-Pointer Ownership Issues in ARC и NSError and __autoreleasing.
Вкратце: указатель на __strong
переменная не может быть передана как указатель на __autoreleasing
. Чтобы поддержать это, компилятор вводит скрытую временную переменную и вместо этого передает свой адрес. То есть ваш код эффективно скомпилирован как:
UIView *view = [UIView new];
NSLog(@"%p",&view);
UIView __autoreleasing * compilerTemp = view;
[self test:&compilerTemp];
view = compilerTemp;
Следовательно, почему вы видите другой адрес.
Спасибо, ваш ответ действительно точным. Обратный инженерный результат работал, как вы говорите. И адреса в MRC одинаковы. – Zentopia