因此,很容易得到一个对象指针的“内存地址”,ála..
id x = @"obj"; printf("'x' is at: %p", x);
'x' is at: 0x100b60048
令人惊讶的是,我似乎无法找到关于如何执行“反向”操作的任何参考。即。通过十六进制int
指针地址获取对象指针的引用,或者它的字符串表示...
NSString * ptr = @"0x100b60048";
unsigned addr = 0;
NSScanner * scn = [NSScanner scannerWithString:ptr];
[scn scanHexInt:&addr];
我确实遇到过以下“方式”,但它a)不起作用(它崩溃)和b)感谢编译器的脆弱感受(又称,它发出警告,哈哈)。
id z = (__bridge id)((void*)addr);
那么,什么是“正确”,现代,ARC兼容的方式来做到这一点?
答案 0 :(得分:2)
那么,"是什么",现代的,与ARC兼容的方式呢?
正确的方法?不要这样做。
对于在ARC应用程序中保留在内存中的对象,需要强烈引用所述对象(或者你必须使用CF API做一些非常讨厌的事情)。任何指针在字符串中只会在应用程序的生命周期内有效;退出并重启?所有地址现在都是虚假的。
所以,如果你真的想引用字符串中的随机对象,那么这样做:
这样,你就不必在int和ptr之间进行转换,你不必使用大量危险的类型转换来安静编译器,你的代码将与ARC兼容。
答案 1 :(得分:1)
所以这很有效。话虽如此,在我的一个项目中依赖于此,我会感到非常不舒服。如果在扫描其地址之前释放该变量,谁知道您将获得什么。在这方面,我想这打破了“ARC兼容”标准,因为谁知道什么时候该参考将被释放,这使得这非常危险。此外,类型安全完全没有窗外。
NSString *pointer = @"test";
NSString *address = [NSString stringWithFormat:@"%p",pointer];
NSString *retrievedObject;
sscanf([address cStringUsingEncoding:NSUTF8StringEncoding], "%p", &retrievedObject);
答案 2 :(得分:0)
好吧,我确实找到了一种相对无痛的方法来做到这一点,所以我会在这里发布它用于欺侮/挑剔甚至,<喘气> ...... 可能接受 ......使用原始问题的变量......
/// this requires a "0x" formatted hex string
ptr = [ptr hasPrefix:@"0x"] ? ptr :
[@"0x" stringByAppendingString:ptr];
uintptr_t hex = strtoull(ptr.UTF8String, NULL, 0);
id gotcha = (__bridge id)(void *)hex;