- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我对 ARC 中的 weak
属性有疑问(自动引用计数)
我的理解(如有错误请指正):
weak
属性的行为类似于 assign
属性,不同之处在于当该属性指向的实例被销毁时,ivar 将指向 nil。
问题:
weak
属性的getter retains和autoreleases。它不应该像 assign
属性的 getter 一样,其中 getter 不保留和自动释放吗?(请引用程序)程序:
我在下面给出了程序的实际输出和我的预期输出。
注意 - 当我将属性从 weak
更改为 assign
时,我的预期输出得到满足
#import<Foundation/Foundation.h>
@interface A : NSObject
- (void) dealloc;
@end
@implementation A
- (void) dealloc
{
printf("\tinstance of A deallocated = %p\n", self);
}
@end
@interface B : NSObject
@property (weak) A* xa1;
- (void) dealloc;
@end
@implementation B
@synthesize xa1;
- (void) dealloc
{
printf("\tinstance of B deallocated = %p\n", self);
}
@end
int main()
{
B* b1 = [[B alloc] init];
@autoreleasepool //autoreleasepool 1
{
{ //block 1
A* a1 = [[A alloc] init];
printf("\ta1 = %p\n", a1);
b1.xa1 = a1;
A* a3 = b1.xa1;
printf("--- end of block 1\n");
} //at this point i expected instance pointed by a1 to be destroyed
printf("--- end of autoreleasepool 1\n");
}
printf("---- end of main\n");
return(0);
}
实际输出:
a1 = 0x10d713f50
--- end of block 1
--- end of autoreleasepool 1
instance of A deallocated = 0x10d713f50
---- end of main
instance of B deallocated = 0x10d713d30
我的预期输出:
a1 = 0x10d713f50
--- end of block 1
instance of A deallocated = 0x10d713f50
--- end of autoreleasepool 1
---- end of main
instance of B deallocated = 0x10d713d30
谢谢
最佳答案
在属性上提供 weak
假定 __weak
对 ivar 的所有权,即它只是 @synthesize
的指令。
根据 http://clang.llvm.org/docs/AutomaticReferenceCounting.html §4.2,读取__weak
变量需要保留对象(当然是之后释放):
Reading occurs when performing a lvalue-to-rvalue conversion on an object lvalue.
- For __weak objects, the current pointee is retained and then released at the end of the current full-expression. This must execute atomically with respect to assignments and to the final release of the pointee.
- For all other objects, the lvalue is loaded with primitive semantics.
它没有说明原因,但想一想如果您从 __weak 变量获得的对象在您开始使用它之前就死了会发生什么。弱指针的目的是确保您拥有 nil
或具有众所周知生命周期的有效对象,这就是为什么读取它的值意味着保留指针(然后属性的 getter 返回它自动释放)。
这不是 Obj-C 独有的,它是所有弱指针实现(包括引用计数和垃圾收集)的常用习惯用法。弱指针不能直接给出指针值,它们必须创建指向“持有”对象的强指针,以确保它不会在调用者开始使用它之前就死掉。在 Obj-C 中,它是 retain-autorelease;在 C++ 中,weak_ptr 首先创建 shared_ptr,在垃圾收集环境中,返回一个强引用并默默地延长对象的生命周期。
关于Objective-C - 弱属性 - getter autoreleases(自动引用计数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8148551/
当我们编写 [Obj autorelease] 时会发生什么? 例如: NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; NSM
执行下面的代码会发生什么? Ball *ball = [[[[Ball alloc] init] autorelease] autorelease]; 最佳答案 让我们分解一下: [Ball allo
我有一个运行良好的应用程序。然后我尝试将导航 Controller 嵌入到 tabbarcontroller 中,接下来我知道我在编译过程中开始遇到这些错误。 有人知道为什么会这样吗?某些设置是否被意
在我使用 autorelease 的大部分代码中,对象最终从函数返回。显然 release 不能在此时调用,而 autorelease 是要走的路。然而,在对象将要传递给另一个将保留它的对象的情况下,
我希望开发一个应用程序,其中将根据用户的交互创建“n”个 View 。如果这些 View 中的每一个都是使用 autorelease 动态创建的,那么该 View 何时会真正被释放? 假设有 10 个
在手动内存管理中,你会在哪些场景下进行自动释放 我想做好充分的准备,因为我即将进行一个不使用 ARC 的项目 最佳答案 当您需要从方法返回一个对象并同时放弃所有权时,您通常会使用 autoreleas
- (void)foo { @try { for (id o in os){ @autoreleasepool {
不确定是否有人知道不断重用的 UITableViewCell 数量是否存在实际限制......?首先,我非常了解所有 Obj-C/Apple 内存管理规则,(我将首先声明这一点,这样我不会浪费任何人的
或者:这个 UILabel 用法怎么可能生成 NSMutableDictionary NSInvalidArgumentException? 这是一个非 ARC iOS 应用程序。当 showLabe
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Im getting this error ‘autorelease’ is unavailable: no
我正在尝试将旧代码转换为 ARC 代码。但是,我在以下行收到构建错误 [[token retain] autorelease]; 我按以下顺序收到 3 个错误: -'autorelease'不可用:在
我正在为 iPhone、objective-c 开发。当我们使用自动释放时,对象什么时候真正被释放——当主自动释放池被释放时(即应用程序终止?),或者当本地函数结束时?例如,我想做这样的事情: - (
抱歉,我是 cocoa 编程的新手,我不确定我是否真正理解 nsautoreleasepool 的工作原理。 我读到的所有地方都说 NSAutoreleasePool 负责所有自动释放调用(谈论最后声
我有一个简单的函数,在解码后返回一个 NSString 。我在我的应用程序中经常使用它,每次使用它时,它似乎都会造成内存泄漏(根据“泄漏”工具)。 Leaks 告诉我问题出在我分配要返回的 NSStr
我的应用程序结构如下,核心部分是用 C++ 编写的,并大量使用线程,我正在其上用 Objective C 开发 UI,如果我不执行线程,它工作正常,但我无法禁用、停止线程,UI 在日志中随机崩溃,我可
我的 TableView 有一个自定义单元格,它是我使用界面生成器设计的。在它的 .m 文件中,我有一些这样的代码来从自定义单元格的包中获取 xib。 - (id)initWithStyle:(UIT
我是 IOS 开发的新手,我已经开始学习 objective-c 以针对 IOS 7 进行编程。据我所知,由于自动引用计数,现在编码比以前容易得多。有几件事我不明白。在 MAIN 方法中我们有 aut
假设以下代码, NSString *str=[[NSString alloc] initWithString:@"sagar"]; [str autorelease]; 我多次看到,大多数程序员确实更
clang 允许以下循环语法: for (...) @autorelease { ... } while (...) @autorelease { ... } do @autorelease { ..
从今天早上开始,当我尝试在一个带有 git 实例的项目上使用 gitk 时,它给了我以下错误。从今天起我就再也没有发生过这种情况,而且我已经使用 gitk 几个月了。 我能指出的唯一区别是,今天早上,
我是一名优秀的程序员,十分优秀!