刘maxwell
刘maxwell

Reputation: 305

Why concurrently setting ivar makes bad access error?

I want to directly assign value to an ivar of class concurrently.

I know there will be problem using setter method (self.target = ...) since ARC inner retain and release stuff for strong property. But I'm trying to use ivar.

  1. Is it because the implicit qualifier __strong? But _target is an ivar, so it won't be released outside each dispatch_async block, right?

  2. And if you make the string shorter, iOS system will apply a tagged pointer to _target, why in this case no bad access error happens anymore?

@interface ClassA ()
@property (nonatomic, strong) NSString *target;
@end

@implementation ClassA
- (void)test {
    dispatch_queue_t queue = dispatch_queue_create("parallel", DISPATCH_QUEUE_CONCURRENT);
    for (int i = 0; i < 10000 ; i++) {
        dispatch_async(queue, ^{
            _target = [NSString stringWithFormat:@"aaaaaaaaaaaaaa-%d",i];  //Bad Access Error in releasing, an NSCFString
            //_target = [NSString stringWithFormat:@"aa-%d",i];  //No problem, an NSTaggedPointerString
        });
    }
}
@end

int main(int argc, char * argv[]) {
    ClassA *obj = [[ClassA alloc] init];
    [obj test];
    return 0;
}

Upvotes: 0

Views: 71

Answers (1)

Cy-4AH
Cy-4AH

Reputation: 4585

Using ivar doesn't makes difference: compiler just add retain/release instead of you. You need unsafe_unretained property to disable insertion of retain/release

Upvotes: 2

Related Questions