使用子类阐明 init 方法
clarify init method using subclass
现在这个问题困扰了我很长一段时间,我真的需要有人为我澄清这个问题。
1) 什么是导致 init 方法 return 与您最初尝试通过调用分配的对象不同的对象的唯一标识符?
..遇到这种情况怎么办?
2) 当来自一个 class 的指定初始化器假设 class 有多个方法时,调用其父 class 中的指定初始化器,从而调用 NSObject 的 init 方法;调用父 class init 方法时到底发生了什么?该方法中的 "self" 是什么,以及从其根 class 编辑的 "self" return 是什么?
也许这会回答您的问题:
init
方法与其他任何方法一样,没有什么特别之处 本身 ;
- 方法参数是分配了初始值的局部变量,该值是调用中给出的值;
self
是一个隐藏的方法参数,它的值与所有其他参数一样在调用中传递;
- 该方法的结果隐式标记为
ns_returns_retained
attribute;最后
self
参数隐式标记为 ns_consumed
attribute。
提到的属性会影响 ARC 如何管理引用 returned (ns_returns_retained
) 或传递给 (ns_consumes
) 的方法。这些属性可以显式应用于任何方法。
属性 ns_returns_retained
隐式 应用于 alloc
、copy
、init
、[=25] 中的方法=],以及 new
个家庭;而 ns_consumes
隐式 应用于 init
方法的隐藏 self
参数。
ns_consumes
属性是 init
方法的唯一 "unusual" 特征。它告诉 ARC 被调用的方法拥有传递的对象引用的所有权,因此负责在需要时释放它。所以在 init
方法中找到的常见语句中,调用 superclass init
方法:
self = [super init];
存储在 self
中的当前引用与 调用者对该引用的所有权一起传递给被调用的方法 。当调用的结果被分配回 self
时,ARC 不需要放弃所有权(又名 "release")存储在那里的旧引用 - 所有权已经传递给被调用的方法 - 或取得所有权(又名"retain") 的新引用 - 因为被调用方将其所有权转移回调用方。
上面允许一个init
方法return一个不同引用,而不是它被传递的引用,并释放它被传递的那个。此功能在用户 classes 中不常用,但在许多常见系统 classes 中使用,例如NSString
和 NSNumber
,利用减少所需对象的数量。
以上听起来比实际上更复杂!如果您有具体问题,请按照@MichaelDautermann 在评论中的建议提出新的具体问题。
HTH
附录
作为对评论的回应,以下内容可能会有所帮助。 所有直接在 iPad 上键入的代码,预计会出现错误!
下面的方法是如何工作的?
- (NSString *) doSomething:(NSString *)aLocal
{
aLocal = [super aLocal];
return aLocal;
}
通话中:
NSString *someResult = [someObjectRef doSomething:someLocalVariable];
其中 someObjectRef
是一个变量,其中包含对声明上述方法的对象的引用,someLocalVariable
包含对字符串的引用。
大纲是:
- 创建了一个新的方法调用及其局部变量
aLocal
- 存储在调用者
someLocalVariable
中的引用被复制(它是值而不是它引用的对象)并存储在aLocal
中
- 方法的语句被执行
- 第一条语句是调用superclass中实现的同一个方法,
aLocal
中引用的值传递给这个方法,引用return ed 被调用存储到 aLocal
- 替换以前存储在那里的引用。
- 第二条语句return将存储在
aLocal
中的引用值作为方法结果,并将该引用存储到调用者的someLocalVariable
. 中
None 应该是令人惊讶的,并且引用 return 可能不是传入的引用(它 可能 是,我们没有想知道继承的 doSomething
方法做了什么,它可能只是 return 它传递的内容)。
现在您只需要了解 self
是一个 隐式 传递的参数。这意味着上述方法有效声明为:
- (NSString *) doSomething:(NSString *)aLocal selfRef:(instancetype)self
和 Objective-C 自动提供作为 selfRef
传递的引用并存储到方法的局部变量 self
.
最终将 doSomething
的名称更改为 initAndDoSomething
更改了 ARC 自动处理作为 self
传递的引用的方式以及 returned 以确保不会留下不需要的对象 - 这是通过隐式添加原始答案中提到的属性来完成的。
就是这样,init
方法是只是 方法。不要认为他们很特别,这会夸大他们的自我;-)
HTH
现在这个问题困扰了我很长一段时间,我真的需要有人为我澄清这个问题。
1) 什么是导致 init 方法 return 与您最初尝试通过调用分配的对象不同的对象的唯一标识符? ..遇到这种情况怎么办?
2) 当来自一个 class 的指定初始化器假设 class 有多个方法时,调用其父 class 中的指定初始化器,从而调用 NSObject 的 init 方法;调用父 class init 方法时到底发生了什么?该方法中的 "self" 是什么,以及从其根 class 编辑的 "self" return 是什么?
也许这会回答您的问题:
init
方法与其他任何方法一样,没有什么特别之处 本身 ;- 方法参数是分配了初始值的局部变量,该值是调用中给出的值;
self
是一个隐藏的方法参数,它的值与所有其他参数一样在调用中传递;- 该方法的结果隐式标记为
ns_returns_retained
attribute;最后 self
参数隐式标记为ns_consumed
attribute。
提到的属性会影响 ARC 如何管理引用 returned (ns_returns_retained
) 或传递给 (ns_consumes
) 的方法。这些属性可以显式应用于任何方法。
属性 ns_returns_retained
隐式 应用于 alloc
、copy
、init
、[=25] 中的方法=],以及 new
个家庭;而 ns_consumes
隐式 应用于 init
方法的隐藏 self
参数。
ns_consumes
属性是 init
方法的唯一 "unusual" 特征。它告诉 ARC 被调用的方法拥有传递的对象引用的所有权,因此负责在需要时释放它。所以在 init
方法中找到的常见语句中,调用 superclass init
方法:
self = [super init];
存储在 self
中的当前引用与 调用者对该引用的所有权一起传递给被调用的方法 。当调用的结果被分配回 self
时,ARC 不需要放弃所有权(又名 "release")存储在那里的旧引用 - 所有权已经传递给被调用的方法 - 或取得所有权(又名"retain") 的新引用 - 因为被调用方将其所有权转移回调用方。
上面允许一个init
方法return一个不同引用,而不是它被传递的引用,并释放它被传递的那个。此功能在用户 classes 中不常用,但在许多常见系统 classes 中使用,例如NSString
和 NSNumber
,利用减少所需对象的数量。
以上听起来比实际上更复杂!如果您有具体问题,请按照@MichaelDautermann 在评论中的建议提出新的具体问题。
HTH
附录
作为对评论的回应,以下内容可能会有所帮助。 所有直接在 iPad 上键入的代码,预计会出现错误!
下面的方法是如何工作的?
- (NSString *) doSomething:(NSString *)aLocal
{
aLocal = [super aLocal];
return aLocal;
}
通话中:
NSString *someResult = [someObjectRef doSomething:someLocalVariable];
其中 someObjectRef
是一个变量,其中包含对声明上述方法的对象的引用,someLocalVariable
包含对字符串的引用。
大纲是:
- 创建了一个新的方法调用及其局部变量
aLocal
- 存储在调用者
someLocalVariable
中的引用被复制(它是值而不是它引用的对象)并存储在aLocal
中
- 方法的语句被执行
- 第一条语句是调用superclass中实现的同一个方法,
aLocal
中引用的值传递给这个方法,引用return ed 被调用存储到aLocal
- 替换以前存储在那里的引用。 - 第二条语句return将存储在
aLocal
中的引用值作为方法结果,并将该引用存储到调用者的someLocalVariable
. 中
None 应该是令人惊讶的,并且引用 return 可能不是传入的引用(它 可能 是,我们没有想知道继承的 doSomething
方法做了什么,它可能只是 return 它传递的内容)。
现在您只需要了解 self
是一个 隐式 传递的参数。这意味着上述方法有效声明为:
- (NSString *) doSomething:(NSString *)aLocal selfRef:(instancetype)self
和 Objective-C 自动提供作为 selfRef
传递的引用并存储到方法的局部变量 self
.
最终将 doSomething
的名称更改为 initAndDoSomething
更改了 ARC 自动处理作为 self
传递的引用的方式以及 returned 以确保不会留下不需要的对象 - 这是通过隐式添加原始答案中提到的属性来完成的。
就是这样,init
方法是只是 方法。不要认为他们很特别,这会夸大他们的自我;-)
HTH