私有成员属性
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
即可。