Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS ARC - weak and strong properties

I'm trying to understand the way ARC works, and as far as I know, I should be doing something wrong here. This is the code I'm using:

Interface:

@interface ViewController : UIViewController{

}

@property (strong, nonatomic) NSString * myString ; 
@property (weak, nonatomic) NSString * myPointer ;

Implementation:

 - (void)viewDidLoad{

     [super viewDidLoad];
     self.myString = @"Hello world!" ; // myString is strong
     self.myPointer = self.myString ; // myPointer var is weak

     [self performSelector:@selector(makeNilMyValue) withObject:nil afterDelay:1];    
     [self performSelector:@selector(printValues) withObject:nil afterDelay:2];    
}

 - (void) makeNilMyValue{
     self.myString = nil ; 
}

 - (void) printValues{
     NSLog(@"myString: %@", self.myString) ;
     NSLog(@"myPointer: %@", self.myPointer) ; 
 }

After executing this, I get:

2012-02-26 11:40:41.652 test1[933:207] myString: (null)

2012-02-26 11:40:41.653 test1[933:207] myPointer: Hello world!

If I'm not wrong, due to myPointer is weak, it shouldn't retain the content of the object. So, it should show nil instead of "Hello World!".

What am I doing wrong?

Following Caleb's answer, I have created another weak pointer, see code below:

- (void)viewDidLoad{
    [super viewDidLoad];
    self.myString = @"Hello world!" ; // myString is strong
    self.myPointer = self.myString ; // myPointer var is weak
    self.myPointer2 = self.myString ; // myPointer2 var is weak

    [self performSelector:@selector(makeNilMyValue) withObject:nil afterDelay:1];    
    [self performSelector:@selector(printValues) withObject:nil afterDelay:2];    
}

- (void) makeNilMyValue{
    self.myPointer2 = @"value changed!" ;
    self.myString = nil ;

}

- (void) printValues{
    NSLog(@"myString: %@", self.myString) ;
    NSLog(@"myPointer: %@", self.myPointer) ;
}

The point is that I still got the same answer I used to have:

2012-02-26 12:08:13.426 test1[1333:207] myString: (null)
2012-02-26 12:08:13.427 test1[1333:207] myPointer: Hello world!
like image 594
RGML Avatar asked Feb 26 '12 11:02

RGML


People also ask

What is weak and strong property in IOS?

strong is the default. An object remains “alive” as long as there is a strong pointer to it. 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.

What is strong and weak in IOS Swift?

For example, a strong reference keeps a firm hold on instances and doesn't allow deallocation by ARC. Similarly, a weak reference cannot protect the instances from being deallocated by ARC. Before you learn about strong and weak reference, make sure to understand how classes and objects work in Swift.

What is the difference between strong weak and unowned in Swift?

The key difference between a strong and a weak or unowned reference is that a strong reference prevents the class instance it points to from being deallocated. That is very important to understand and remember. ARC keeps track of the number of strong references to a class instance.

What is strong in IOS?

By Aasif Khan | December 9, 2021 6:15 pm | 5-min read. Creating a strong reference to an instance in Swift, means that the instance is kept in the iPhone's memory until you're done with it. You can also create weak references. Both are part of the memory management mechanism called ARC.


2 Answers

So, it should show nil instead of "Hello World!".

Constant strings are never deallocated, so your `@"Hello World!" never goes away. This is why your weak reference is never set to nil.

like image 42
Caleb Avatar answered Sep 27 '22 23:09

Caleb


As Caleb pointed out, using a constant NSString for this example is not a good idea.

The simplest way to create a string object in source code is to use the Objective-C @"..." construct:

NSString *temp = @"/tmp/scratch"; Note that, when creating a string constant in this fashion, you should avoid using anything but 7-bit ASCII characters. Such an object is created at compile time and exists throughout your program’s execution. The compiler makes such object constants unique on a per-module basis, and they’re never deallocated, though you can retain and release them as you do any other object. You can also send messages directly to a string constant as you do any other string:

BOOL same = [@"comparison" isEqualToString:myString];

The documentation explains that constant strings will never disappear.

Try using something else for your experiment. I tried NSObject and it produced expected results.

Interface:

@interface ViewController : UIViewController

@property (strong, nonatomic) NSObject * myString; 
@property (weak, nonatomic) NSObject * myPointer;

@end

Implementation:

@implementation ViewController

@synthesize myString = _myString;
@synthesize myPointer = _myPointer;

- (void)viewDidLoad{

    [super viewDidLoad];

    self.myString = [[NSObject alloc] init];
    self.myPointer = self.myString;
    self.myString = nil; 
    NSLog(@"myString: %@", self.myString);
    NSLog(@"myPointer: %@", self.myPointer);
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

@end

Weak pointers are set to nil when there are no strong pointers to the memory as explained in the documentation - Apple Developer or llvm.

__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.

like image 160
Jiri Avatar answered Sep 27 '22 23:09

Jiri