0

i declare two properties on header file: @property(strong)NSString *p1; @property(assign)NSString *p4; now on implementation file, i write two method to test assign property:

- (void)testAssign {
    NSString *rawString = @"Hello, ";
    NSString *resultString = [rawString stringByAppendingString:@"World"];
    self.p4 = resultString;
    resultString = nil;
    (@"My group is %@", self.p4);

 }

On this scene will be an error.

but when the code as below , this do well:

- (void)testString {
    NSString *rawString = @"Hello, ";
    NSString *resultString = [rawString stringByAppendingString:@"World"];
    self.p4 = resultString;
    self.p1 = resultString;
    NSLog(@"now result is %@, %@", self.p4, self.p1);
    resultString = nil;
    NSLog(@"now result is %@, %@", self.p4, self.p1);
    self.p1 = nil;
    NSLog(@"now result is %@, %@", self.p4, self.p1);
 }

the result is :

2014-06-29 19:10:55.798 TestDemo[20853:303] now result is Hello, World, Hello, World
2014-06-29 19:10:55.798 TestDemo[20853:303] now result is Hello, World, Hello, World
2014-06-29 19:10:55.799 TestDemo[20853:303] now result is Hello, World, (null)

what happen on the second snippet? why is there no error?

maple
  • 101
  • 1
  • 13

1 Answers1

2

You receive an access violation in the first snippet due to the use of an assign property and releasing the object that it points to.

You don't get one in the second snippet even though it should have the same problem - both the local variable reference and the strong property reference are nilled, which should leave an invalid pointer.

My suspicion is that this is just something to do with compiler optimisation and timing. If I single step in the debugger, both snippets work fine, indicating that the single-step process is also changing things.

In the second case you are looking at an eventual crash if you continue to access p4, which I confirmed by calling your code in my app delegate, didFinishLaunching and then accessing self.p4 from willResignActive. Enabling Zombies makes it even clearer - "message sent to deallocated instance" in both cases.

Under ARC weak is preferred as this will replace the invalid reference with 'nil' - you will still have a bug, but not a crash.

See also - Objective-C ARC: strong vs retain and weak vs assign

Community
  • 1
  • 1
Paulw11
  • 108,386
  • 14
  • 159
  • 186
  • thanks your reply. if i have a breakpoint at NSLog on first snippet there is no crash, what happen? you say when i execute the second snippet and then call `self.p4` there is no crash. I will check your link – maple Jun 29 '14 at 12:48