私有成员属性
ObjC的私有成员属性
iOS的ObjC的私有属性,指的是:
- 大括号{}内部的- 属性名往往是以下划线开头的
 
- 且外部没有对应的同名的@property的属性
举例
AAURLSession
@interface AAURLSession : NSObject <NSURLSessionDataDelegate, NSURLSessionDelegate, NSURLSessionTaskDelegate>
{
...
    NSObject<OS_dispatch_queue> *_sessionQueue;
...
}
WAPreparedRegistrationURL
WhatsApp/headers/WhatsApp_v23.20.79_headers_WhatsApp/WAPreparedRegistrationURL.h
#import <objc/NSObject.h>
@class NSArray, NSString, NSURL;
@interface WAPreparedRegistrationURL : NSObject
{
    NSString *_baseURLString;
    NSArray *_params;
    NSURL *_proxyURL;
}
- (void).cxx_destruct;
- (id)urlWithTokenArray:(id)arg1;
- (id)urlWithRegistrationToken:(id)arg1 backupToken:(id)arg2;
- (id)initWithBaseURLString:(id)arg1 params:(id)arg2 encryptWithProxyURL:(id)arg3;
@end
-》
- 类WAPreparedRegistrationURL的私有属性- _baseURLString
- _params
- _proxyURL
 
访问私有成员属性的方式
下面以WAPreparedRegistrationURL为例,来介绍有多种方式可以查看私有成员属性值:
Xcode调试时,有对应的类的实例:
(lldb) po 0x0000000282170b80
<WAPreparedRegistrationURL: 0x282170b80>
想要查看:
- 类的WAPreparedRegistrationURL的私有属性=成员=变量的值- _baseURLString
 
具体方式:
valueForKey
- 语法: - po [objcObj valueForKey: @"_xxx"]- 属性名不带下划线也可以:po [objcObj valueForKey: @"xxx"]
 
- 属性名不带下划线也可以:
- 举例 
(lldb) po [0x282170b80 valueForKey: @"_baseURLString"]
https://v.whatsapp.net/v2/exist
(lldb) po [0x282170b80 valueForKey: @"baseURLString"]
https://v.whatsapp.net/v2/exist
指针
- 语法po ((ClassName*)instanceAddress)->privatePropertyName
- 举例(lldb) po ((WAPreparedRegistrationURL*)0x282170b80)->_baseURLString https://v.whatsapp.net/v2/exist
偏移量+内存值 == 自己计算指针和内存中的值
(lldb) p/x 0x282170b80 + 0x08
(long) $18 = 0x0000000282170b88
(lldb) x/2gx 0x0000000282170b88
0x282170b88: 0x00000002833bbf80 0x000000028680ed90
(lldb) po 0x00000002833bbf80
https://v.whatsapp.net/v2/exist
其中:
- 0x282170b80 + 0x08==- ((*WAPreparedRegistrationURL)0x282170b80)->_baseURLString
- 而内存地址是:0x00000002833bbf80- 其中保存的内容,就是:NSString*类型的URL值了
 
- 其中保存的内容,就是:
常见错误
- 用点.去访问:不带下划线,是无法访问的
(lldb) po ((WAPreparedRegistrationURL*)0x282170b80).baseURLString
error: expression failed to parse:
error: <user expression 23>:1:43: property 'baseURLString' not found on object of type 'WAPreparedRegistrationURL *'
((WAPreparedRegistrationURL*)0x282170b80).baseURLString
                                          ^
- 用点.去访问:带下划线,虽然也可以打印出值的- 但其实语法是错误的,但会自动会告诉你正确的语法:用指针->访问
 
(lldb) po ((WAPreparedRegistrationURL*)0x282170b80)._baseURLString
https://v.whatsapp.net/v2/exist
  Fix-it applied, fixed expression was: 
    ((WAPreparedRegistrationURL*)0x282170b80)->_baseURLString
- po无法,以ObjC的语法,去直接查看属性名(不论是带下划线还是不带下划线)-》 都会报错
(lldb) po [0x282170b80 baseURLString]
error: Execution was interrupted, reason: Attempted to dereference an invalid ObjC Object or send it an unrecognized selector.
The process has been returned to the state before expression evaluation.
(lldb) po [0x282170b80 _baseURLString]
error: Execution was interrupted, reason: Attempted to dereference an invalid ObjC Object or send it an unrecognized selector.
The process has been returned to the state before expression evaluation.
- 用指针访问时,不带下划线的话,会报报语法错误:找不到属性名=成员名=member
(lldb) po ((WAPreparedRegistrationURL*)0x282170b80)->baseURLString
error: expression failed to parse:
error: <user expression 17>:1:44: 'WAPreparedRegistrationURL' does not have a member named 'baseURLString'
((WAPreparedRegistrationURL*)0x282170b80)->baseURLString
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  ^
即可。