Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 为什么[NSData字节]可以更改并影响NSData对象本身_Objective C - Fatal编程技术网

Objective c 为什么[NSData字节]可以更改并影响NSData对象本身

Objective c 为什么[NSData字节]可以更改并影响NSData对象本身,objective-c,Objective C,假设我有来自另一个人的以下代码: -(NSString *)xorBetweenString1:(NSString *)str1 andString2:(NSString *)str2 { NSData *d1 = [str1 dataUsingEncoding:4]; const void *b1 = [d1 bytes]; NSData *d2 = [str2 dataUsingEncoding:4]; const void *b2 = [d2 bytes]

假设我有来自另一个人的以下代码:

-(NSString *)xorBetweenString1:(NSString *)str1 andString2:(NSString *)str2 {
    NSData *d1 = [str1 dataUsingEncoding:4];
    const void *b1 = [d1 bytes];

    NSData *d2 = [str2 dataUsingEncoding:4];
    const void *b2 = [d2 bytes];
    const void *b3 = b2;

    int c = 0;
    for (int i = 0; i < [d1 length]; i ++) {
        *(Byte *)b1++ ^= *(Byte *)b3++;
        c++;
        if (c == [str2 length]) {
            c = 0;
            b3 = b2;
        }
    }

    NSString *result = [[NSString alloc] initWithData:d1 encoding:4];
    return result;
}
STRING1:(NSString*)str1和STRING2:(NSString*)str2之间的
-(NSString*)XOR{
NSData*d1=[str1数据使用编码:4];
常量void*b1=[d1字节];
NSData*d2=[str2数据使用编码:4];
常量void*b2=[d2字节];
常数void*b3=b2;
int c=0;
对于(int i=0;i<[d1长度];i++){
*(字节*)b1++^=*(字节*)b3++;
C++;
如果(c==[str2长度]){
c=0;
b3=b2;
}
}
NSString*result=[[NSString alloc]initWithData:d1编码:4];
返回结果;
}
我记得,[NSData bytes]返回
const void*
,这意味着指针指向的内容是不可变的。但是,上述功能确实改变了NSData的内容:

之前:

(lldb)po v20

之后:

(lldb)po v20

我很困惑,为什么没有错误?还是我犯了什么错误

更新:
我发现[str1 datausingencode:4]正在返回
nsconcertemutabledata
。似乎是根本原因。但是为什么它返回的是
nsconcreteumtabledata
,而不是纯
NSData
?我的意思是苹果文档从来没有提到过它?

上面的代码是允许的,不是因为幕后有一个
nsconcreteumtabledata
,而是因为作者正在将
const
指针投射到一个非
const
指针。在Objective-C中,在进行强制转换时,可以绕过所有类型和易变性安全

bytes
引用所指向的数据的这种变异是一种可怕的做法,因为您无法确定此
NSData
可能对该基础数据缓冲区做出了哪些假设或操作。您应该执行
mutableCopy
以获取
NSMutableData
,然后使用
mutableBytes
或使用
replaceBytes…
方法之一

正如
mutableBytes
所述:

此[
mutableBytes
]属性与
bytes
属性类似,但不同。
bytes
属性包含指向常量的指针。可以使用
bytes
指针读取数据对象管理的数据,但不能修改该数据。但是,如果
mutableBytes
属性包含非空指针,则该指针指向可变数据。您可以使用
mutableBytes
指针修改数据对象管理的数据


我希望这段代码是从反汇编程序生成的。。。此外,未定义的行为也是未定义的。崩溃或任何运行时错误都是您幸运时的最佳结果。@BryanChen不,我发现的原因是它首先返回NSConcreteModableData。这就是为什么它是可变的。但是为什么可变数据不是NSData呢?苹果文档说它是
NSData
,所以它是
NSData
。你只需要知道这些。实施细节仅用于性能优化,您不需要了解和关心它。不要编写任何依赖于它的代码,因为苹果可以在下一次操作系统小更新时更改它,而不必提及它。它很可能返回不同的NSData包装器,具体取决于您使用的编码类型。如果它是这样使用的,它可能应该是可变的。它真的打碎了什么东西,还是你只是好奇?@rmaddy,来自Rhi Rob,谢谢你的回答。由于作者正在将常量指针强制转换为非常量指针,您能否进一步介绍
?我这里不清楚。我看到它们都是const void*(Byte*)可以给我任何文档吗?如果你跳转到Xcode中的
Byte
的定义,你会发现它只是
UInt8
typedef
,而
unsigned char
typedef
。因此,这是采用
v19
,将其强制转换为指向
无符号字符的非
常量
指针,然后取消引用以更改其指向的字节。