An objective-c variable being assigned a value from a mutable array element is not being correctly assigned a type

huangapple go评论54阅读模式
英文:

An objective-c variable being assigned a value from a mutable array element is not being correctly assigned a type

问题

我遇到了一个无法解释的情况,无法解释为什么会发生,无法修复它,也无法找到解决方法。我有一个可变对象数组,其中包含不定数量的对象。每个对象要么是一个字符串文件名,要么是一个Web位置的URL。我还有另一个可变整数对象数组,用于标识第一个数组中特定索引处的对象类型,要么是字符串文件名(0),要么是URL(1)。现在,我需要访问并使用第一个数组中的元素。我使用以下代码来索引对象并选择一个对象:myObject = [ArrayName objectAtIndex:index]。监视此行代码的执行会显示,即使已将myObject定义为NSString,它也会变成URL类型的对象。如果我尝试将myObject用作字符串,它会引发执行错误,说myObject是URL。

我尝试过将myObject类型定义为字符串,但它不起作用。相反,如果我尝试使用NSURLURLWithStringNSStringstringWithContentsOfURL:encoding:error:myObject转换为字符串,当将myObject用作URL时会失败。所以我陷入了困境,一组方法认为它是另一种类型的对象,另一组方法认为它是另一种类型的对象。调试器是怎么想到字符串对象是URL类型的我不知道。其他问题并没有确切解决这种情况。 欢迎任何想法或解决方法。

英文:

I have a situation I can’t explain why is happening, can’t fix it, and can’t figure a work around for it. I have a mutable object array that holds a variable number of objects. Each object is either a string file name or a URL of a web location. I have another mutable array of integer objects that identifies the type of object at a particular index in the first array, either a 0 for string file name, or a 1 for a URL. Now, I need to access and use the elements in the first array. I index the objects and select an object with: myObject = [ArrayName objectAtIndex:index]. Monitoring the execution of this line of code reveals that myObject becomes a URL type object even if it has been defined as an NSString. If I attempt to use myObject as a string it throws an execution error saying myObject is a URL.

I’ve tried typedefing myObject as a string but it won’t take. Conversely if I attempt to convert myObject to a string using NSURL’s URLWithString or NSString’s stringWithContentsOfURL: encoding:error: which failed when using myObject as a URL. So I’m stuck, one set of methods thinks its another type of object, the other type of methods thinks its the other type of object. Where the debugger gets the ides that the string object is a URL I have no idea. Other questions don't exactly address this situation.
Any ideas or work arounds would be welcome.

答案1

得分: 4

我相信你有一个类似这样的NSArray(在这个问题中,NSArray和NSMutableArray之间没有重要的区别):

NSArray *array = @[
    @"This is a string",
    [NSURL URLWithString:@"https://stackoverflow.com"],
];

每个元素可能是不同的类型。因此,在提取元素时,你唯一可以使用的类型是id("some object"):

id item = array[0];

现在你需要弄清楚它是什么类型。你可以使用-isKindOfClass:来做到这一点。例如:

if ([item isKindOfClass:[NSString class]]) {
    // 由于已知它是一个NSString,将其分配一个类型以提高类型安全性。
    // 这样,如果调用不正确的方法,编译器将提供警告。
    NSString *string = item;
    NSLog(@"This is a string with length: %lu", (unsigned long)[string length]);
} else if ([item isKindOfClass:[NSURL class]]) {
    NSURL *url = item;
    NSLog(@"This is a URL with absoluteString: %@", 
);
} else { NSLog(@"数组中发现了意外的类型: %@", [item class]); }

如果你编写类似NSString *item = array[0]的代码,Objective-C会假设你确信该元素是NSString。这并不会使它成为一个NSString。如果你错了,发送一个NSString不响应的消息,程序将崩溃。

一般来说,多类型(异构)数组是一个不好的主意。编译器依赖程序员来做一切正确,帮助有限。但在某些情况下,它们非常有用,是Objective-C的一个强大特性。

你应该强烈避免使用一个单独的数组来跟踪类型。这只会导致不同步并引发问题。

英文:

I believe you have an NSArray like this (there's no important difference here between NSArray and NSMutableArray for this question):

NSArray *array = @[
    @"This is a string",
    [NSURL URLWithString:@"https://stackoverflow.com"],
];

Each element may be a different type. So when fetching elements, the only type you can really use is id ("some object"):

id item = array[0];

Now you need to figure out what type it is. You can do that with -isKindOfClass:. For example:

if ([item isKindOfClass:[NSString class]]) {
    // Since it's known to be an NSString, assign it a type to improve type-safety.
    // This way the compiler will provide warnings if incorrect methods are called.
    NSString *string = item;
    NSLog(@"This is a string with length: %lu", (unsigned long)[string length]);
} else if ([item isKindOfClass:[NSURL class]]) {
    NSURL *url = item;
    NSLog(@"This is a URL with absoluteString: %@", 
); } else { NSLog(@"Unexpected type found in array: %@", [item class]); }

If you write something like NSString *item = array[0], Objective-C will assume you know for certain that the element is an NSString. That does not make it an NSString. If you're wrong, and you send a message that NSString doesn't respond to, the program will crash.

Generally speaking, multi-type (heterogeneous) arrays are a bad idea. The compiler relies on the programmer to do everything correctly, and can't help very much. But in some cases they're extremely useful, and a powerful feature of Objective-C.

You should strongly avoid having a separate array that keeps track of the types. That's just begging to be out of sync and cause problems.

huangapple
  • 本文由 发表于 2023年3月4日 02:05:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75630479.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定