Reputation: 6952
This is my code
__weak KDObject *obj = [KDObject fetchObj] ;
NSLog(@"%@", obj) ; // I think it should be nil, but it is not
obj.i = 10 ;
NSLog(@"%d", obj.i) ;
In KDObject.m
@implementation KDObject
+ (instancetype)fetchObj
{
return [[self alloc] init] ;
}
@end
the result is the same whatever KDOjbect.m is compile with -fno-objc-arc
flag or without -fno-objc-arc
flag
Anybody has ideas why obj
is not nil ?
Upvotes: 0
Views: 125
Reputation: 4884
- (void)loadView
{
[super loadView];
TestObject *obj_ = [[TestObject alloc] init];
pObj = obj_;
if(pObj == nil)
{
NSLog(@"pObj_ is not nil");
}
__weak TestObject *obj2_ = [[TestObject alloc] init];
if(obj2_ == nil)
{
NSLog(@"obj2_ is nil");
}
__weak TestObject *obj3_ = [TestObject createInstance];
if(obj3_ == nil)
{
NSLog(@"obj3_ is nil");
}
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if(pObj == nil)
{
NSLog(@"pObj is nil");
}
}
KudoCC requested this code. I used LLVM5.1. If I use -fno-objc-arc to TestObject.h, the objc3_ became not nil.
Upvotes: -1
Reputation: 16660
Related to your Q and to your answer:
-fectchObject is a method not belonging to any method family with ownership transfer. Therefore ARC has to ensure that returning the reference is safe. That means that losing the strong reference in the local scope of -fetchObject does not give up the last reference.
One way to accomplish this is to use the autorelease pool. But ARC does not guarantee that the ARP is used. Moreover it tries not to use the ARP, because it is the solution with the highest memory pressure.
So the things happening depends of the compiler implementation, attributes set to the method and what the compiler sees in source code (esp. implementation of -fetchObject). So you should not rely on returning in ARP.
__weak is guaranteed to be nil, if the object is destroyed. But it is not guaranteed that the object is destroyed in the earliest possible moment. This is subject of optimization.
Upvotes: 2
Reputation: 8066
From the docs about __weak
__weak specifies a reference that does not keep the referenced object alive. A weak reference is set to nil when there are no strong references to the object.
Whether it's __weak or not KDObject *o = [[KDObject alloc] init]
creates an object so o
is not nil.
__weak is something realated to memory management. If none of strong objects are pointing to a weak
object, it would be released from memory.
Upvotes: 0