现在我已经把这个问题蒙上阴影了很长一段时间,我真的需要有人为我澄清这一点。
1)什么是唯一标识符,导致init方法返回除最初尝试通过调用分配的对象之外的其他对象? 在这种情况下你应该怎么做?
2)当一个类的指定初始值设定项假设该类有多个方法时,在其父类中调用指定的初始值设定项,从而调用NSObject的init方法;调用父类init方法时究竟发生了什么?什么是"自我"在该方法明确引用,以及" self"从它的根类返回?
答案 0 :(得分:1)
也许这会回答你的问题:
init
方法只是一种方法,其中没有什么特别的本身; self
是一个隐藏的方法参数,在调用中传递的值与所有其他参数一样; ns_returns_retained
attribute隐式标记;最后self
参数隐式标有ns_consumed
attribute。提到的属性影响ARC如何管理由(ns_returns_retained
)方法返回的引用(ns_consumes
)或传递给它的{ns_returns_retained
)。这些属性可以显式应用于任何方法。
属性alloc
将隐式应用于copy
,init
,mutableCopy
,new
和{中的方法{1}}家庭;而ns_consumes
隐式应用于self
方法的隐藏init
参数。
ns_consumes
属性是init
方法的唯一“异常”功能。它告诉ARC,被调用的方法取得了传递的对象引用的所有权,因此负责在需要时释放它。因此,在init
方法中的通用语句中,调用超类init
方法:
self = [super init];
将self
中存储的当前引用传递给被调用方法以及该引用的调用者所有权。当呼叫结果被分配回self
时,ARC不需要放弃所有权(也称为“释放”)存储在那里的旧引用 - 所有权已经传递给被调用方法 - 或取得所有权(又称“保留”) “)新引用 - 当被叫将其所有权转移给调用者时。
上面的方法允许init
方法返回不同的引用而不是它传递的引用,并释放它传递的引用。此功能通常不在用户类中使用,而是在许多常见系统类中使用,例如NSString
和NSNumber
,可以减少所需对象的数量。
以上听起来比这更复杂!如果您有具体问题,请在@MichaelDautermann的评论中提出新的具体问题。
HTH
<强>附录强>
在回复评论时,以下内容可能有所帮助。 所有代码都直接在iPad上输入,预计会出现错误!
以下方法如何运作?
- (NSString *) doSomething:(NSString *)aLocal
{
aLocal = [super aLocal];
return aLocal;
}
在电话中:
NSString *someResult = [someObjectRef doSomething:someLocalVariable];
其中someObjectRef
是一个变量,其中包含对声明上述方法的对象的引用,someLocalVariable
包含对字符串的引用。
概括为:
aLocal
someLocalVariable
中的引用被复制(它的值不是它引用的对象)并存储在aLocal
aLocal
中引用的值传递给此方法,并且调用返回的引用存储到{{1} } - 替换先前存储在那里的引用。aLocal
中存储的引用值作为方法结果,该引用存储在调用者的aLocal
中。这些都不应该令人惊讶,并且引用返回可能不是传入的引用(可以,我们不知道继承的someLocalVariable
方法做什么,它可能只是返回通过的内容。
现在您需要了解的是doSomething
是隐式传递的参数。这意味着上述方法有效地声明为:
self
和Objective-C自动提供传递为- (NSString *) doSomething:(NSString *)aLocal selfRef:(instancetype)self
的引用并存储到方法的局部变量selfRef
中。
最后将self
的名称更改为,例如doSomething
会更改ARC自动处理作为initAndDoSomething
传递的引用的方式,并返回一个以确保不会留下不需要的对象 - 这是通过隐式添加原始答案中提到的属性来完成的。
就是这样,self
方法只是方法。不要认为它们是特殊的,它会膨胀它们的自我; - )
HTH