iOS - assign 修饰词

78 阅读2分钟

Tags: Objective-C, iOS, 修饰词


介绍

assign 修饰词通常用于修饰基础数据类型(如NSInteger、BOOL等)和C数据类型(如int、float,double等)

常用与基本数据类型,也可以作用在对象类型

若作用与对象类型时,会存在野指针的情况,所以我们平时不会通过 assign 来修饰对象类型

实践

Demo 地址:github.com/lishangjing…

@interface ViewController ()
@property (nonatomic, strong) NSString *strongString;
@property (nonatomic, assign) NSString *assignString;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

// MARK: NSString Test

- (IBAction)createNSString:(UIButton *)sender {
    // _strongString    __NSCFConstantString *    @"123"    0x00000001002000b0
    _strongString = @"123";
    
    _assignString = _strongString;
    
    NSLog(@"%@",_strongString); // 123
    NSLog(@"%p",_strongString); // 0x1002000b0
    NSLog(@"%@",_assignString); // 123
    NSLog(@"%p",_assignString); // 0x1002000b0
}

- (IBAction)removeNSString:(id)sender {
    _strongString = nil;
    
    NSLog(@"%@",_strongString);
    NSLog(@"%p",_strongString);
    // createNSString3
    // Thread 1: EXC_BAD_ACCESS (code=2, address=0x4955427e90)
    NSLog(@"%@",_assignString);
    NSLog(@"%p",_assignString);
    
    /**
     2023-08-15 16:38:29.190727+0800 GroceryDemo[17859:6365915] (null)
     2023-08-15 16:38:29.190844+0800 GroceryDemo[17859:6365915] 0x0
     2023-08-15 16:38:29.190910+0800 GroceryDemo[17859:6365915]
     2023-08-15 16:38:29.190970+0800 GroceryDemo[17859:6365915] 0x1097d5e90
     */
}

@end

遇到的问题:

当我尝试用 NSString 来复现该结论时,当我置空字符串时_strongString = nil;

发现 NSString 并没有复现野指针问题,下面是我创建 NSString 的方式,以及赋值

NSString *str2 = [NSString stringWithFormat:@"123"];
NSString *str2 = @"123";

扩展&解决问题:

这里的对象类型中,NSString 存在特殊的情况

  • NSString 不同的创建方式,会创建不同的 NSString 对象 →
    • 不同的 NSString 对象,会决定内存被存放的位置 →
    • 不同的存放位置决定是否会发生野指针(仅存放在中的对象会发生野指针)。
NSString *str1 = [NSString stringWithFormat:@"小强"];
NSString *str2 = [NSString stringWithFormat:@"1"];
NSString *str3 = [NSString stringWithFormat:@"a"];
NSString *str4 = @"123456789";

__NSCFConstantString

显然是常量字符串,自然就是存储在常量区

__NSCFString

表示为oc对象,NSString就是封装的CFString,0x6000000315c0 地址显示这个字符串对象存储在堆中

NSTaggedPointerString

这个类表示这是字符串的一种指针Tagged Pointer。

Untitled 1.png


引用文章: