Val*_*adu 2 cocoa cocoa-touch memory-management objective-c
我最近进入这个关于是否辩论lastObject返回一个自动释放的对象与否.我一直认为它确实存在,而且我从来没有遇到过问题,但是,来考虑一下,大多数时候我使用这种方法,我的收藏品都是参考,所以,显然,即使它只是一个简单的参考,代码将工作正常.因此,关于返回值的自动释放性质,似乎我错了(基于一些SO答案),但是,我试图在Apple的文档中找到关于它的一些内容,但未能这样做.
Apple是否记录了lastObject自动释放它返回的对象?如果是这样,它在哪里记录?如果事实证明这是真的,他们为什么这样做呢?我在上述辩论中得到的答案对我来说没有意义,该集合可以保留并自动释放该对象吗?这样,对象在runloop结束时仍然有效.
尽管没有明确记录,但它可能lastObject具有与之相同的行为objectAtIndex:.objectAtIndex:确实不 retain和autorelease时,返回按本文档对象:避免造成对象您正在使用的重分配.
从其中一个基本集合类中删除对象时,会向其发送一个释放(而不是自动释放)消息.如果集合是已删除对象的唯一所有者,则会立即释放已删除的对象(示例中为heisenObject).
(强调我的)
从同一文档页面考虑此示例:
heisenObject = [array objectAtIndex:n];
[array removeObjectAtIndex:n];
// heisenObject could now be invalid.
Run Code Online (Sandbox Code Playgroud)
在内存管理方面,释放整个数组与删除所有对象相同,因此您不能指望返回的对象在runloop结束之前保持有效,即使它在某些情况下实际上可能没有被释放(例如文字字符串,单例,对象的其他引用等).
如果-[NSArray lastObject]自动释放的对象,这是合理的问:"是记载自动释放对象,这样我可能会依赖于这种行为?"
但是,如果-[NSArray lastObject]不不自动释放对象,没有必要问的行为是否被记录在案.您必须保留返回的对象,如果你想确保它的生命过去removeLastObject或阵列的释放.如果你不保留它,你的程序会行为不端.文档说或不说的并不重要:在这种情况下确保程序正常运行的唯一方法是保留对象.如果他们lastObject将来发生变化以自动释放对象,您的程序仍然会正常运行.
所以,除了别的什么之外,你应该保留这个对象.
但我们可以知道别的东西.我们可以反汇编该-[NSArray lastObject]方法以确定它是否自动释放.然后我们就会知道我们是否应该费心询问文档说的内容.
该-[NSArray lastObject]方法在CoreFoundation框架中实现.我使用Hopper反汇编了OS X 10.8(Mountain Lion)64位版本:
75e30 55 push rbp
75e31 4889E5 mov rbp, rsp
75e34 53 push rbx
75e35 50 push rax
75e36 4889FB mov rbx, rdi
75e39 488D3530971800 lea rsi, qword [ds:objc_msg_count] ; @selector(count)
75e40 4889DF mov rdi, rbx
75e43 FF1527971800 call qword [ds:objc_msg_count] ; @selector(count)
75e49 4885C0 test rax, rax
75e4c 7509 jne 0x75e57
75e4e 31C0 xor eax, eax
75e50 4883C408 add rsp, 0x8
75e54 5B pop rbx
75e55 5D pop rbp
75e56 C3 ret
75e57 48FFC8 dec rax ; XREF=0x75e4c
75e5a 488B0D1F971800 mov rcx, qword [ds:objc_msg_objectAtIndex_] ; @selector(objectAtIndex:)
75e61 488D3518971800 lea rsi, qword [ds:objc_msg_objectAtIndex_] ; @selector(objectAtIndex:)
75e68 4889DF mov rdi, rbx
75e6b 4889C2 mov rdx, rax
75e6e 4883C408 add rsp, 0x8
75e72 5B pop rbx
75e73 5D pop rbp
75e74 FFE1 jmp rcx
Run Code Online (Sandbox Code Playgroud)
如果您说x86汇编程序,您可以将其转换为这个简单的Objective-C代码:
- (id)lastObject {
NSUInteger count = self.count;
return count == 0 ? nil : [self objectAtIndex:count-1];
}
Run Code Online (Sandbox Code Playgroud)
由于有文件证明objectAtIndex并不会自动释放对象,我们可以看到,实际执行-[NSArray lastObject]不自动释放的对象.
这意味着文档所说的并不重要:如果您希望程序正常运行,则必须保留该对象.
请注意,我并不是说您应该依赖实现细节.我只是使用实现来决定是否值得寻找文档.
| 归档时间: |
|
| 查看次数: |
588 次 |
| 最近记录: |