NSUserDefaults 返回一个可变数组

发布于 2024-12-25 08:11:35 字数 2743 浏览 0 评论 0原文

我正在为 MVC 构建模型,但遇到了与 Apple 文档 “从 NSUserDefaults 返回的值是不可变的,即使您将可变对象设置为值。”,[[NSUserDefaults standardUserDefaults] objectForKey:@"key"] 返回一个可变数组。

我在 Xcode 4D199 中为 iOS 创建了一个空应用程序,以重新创建条件并确认它与我的项目中的其他因素无关。

我正在设置 NSMutableArray,如下所示:

- (void)setupTest
{
    NSMutableArray *mutableArray = [[NSMutableArray alloc] init];
    [mutableArray addObject:@"one"];
    [mutableArray addObject:@"two"];

    [[NSUserDefaults standardUserDefaults] setObject:mutableArray forKey:@"mutableArray_01"];
    [[NSUserDefaults standardUserDefaults] synchronize];    
}

并且,我得到的对象如下所示:

- (void)checkTest
{
    NSMutableArray *mutableArrayInCheck = nil;
    id whatIsThis = [[NSUserDefaults standardUserDefaults] objectForKey:@"mutableArray_01"];
    if([whatIsThis isKindOfClass:[NSMutableArray class]])
    {
        NSLog(@"The array is mutable.");
        mutableArrayInCheck = (NSMutableArray *)whatIsThis;
    }
    if([whatIsThis isKindOfClass:[NSArray class]])
    {
        NSLog(@"The array is immutable.");
    }
    if ([whatIsThis isMemberOfClass:[NSMutableArray class]])
    {
        NSLog(@"The array is a member of NSMutableArray class");
    }

    if (mutableArrayInCheck) 
    {
        [mutableArrayInCheck addObject:@"three"];
        NSLog([mutableArrayInCheck description]);
    }
}

现在,根据苹果文档,人们会期望控制台仅显示不可变行。但是当我执行代码时,控制台中会显示以下几行:

2012-01-05 18:47:33.328 Tester_01[78533:f803] The array is mutable.
2012-01-05 18:47:33.348 Tester_01[78533:f803] The array is immutable.
2012-01-05 18:47:33.349 Tester_01[78533:f803] (
    one,
    two,
    three
)

所以,我想知道这里是否缺少某些内容。

有关更多信息,执行测试的代码如下所示:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    BOOL setupKey = NO;
    if (setupKey) 
    {
        [self setupTest];
    }   
    BOOL checkKey = YES;
    if (checkKey)
    {
        [self checkTest];
    }

    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

最初,我将 setupKey 设置为 YES 来运行该项目。第一次运行后,我将 setupKey 更改为 NO。控制台日志是 setupKey 设置为 NO 时的结果。让我知道你的想法。

I am building a model for a MVC and I am experiencing an anomaly where contrary to the Apple Documentation "Values returned from NSUserDefaults are immutable, even if you set a mutable object as the value.", the [[NSUserDefaults standardUserDefaults] objectForKey:@"key"] is returning a mutable array.

I created an empty application for iOS in Xcode 4D199 to re-create the condition and confirm that it isn't accountable to other factors on my project.

I am setting the NSMutableArray as shown:

- (void)setupTest
{
    NSMutableArray *mutableArray = [[NSMutableArray alloc] init];
    [mutableArray addObject:@"one"];
    [mutableArray addObject:@"two"];

    [[NSUserDefaults standardUserDefaults] setObject:mutableArray forKey:@"mutableArray_01"];
    [[NSUserDefaults standardUserDefaults] synchronize];    
}

and, I am getting the object as shown:

- (void)checkTest
{
    NSMutableArray *mutableArrayInCheck = nil;
    id whatIsThis = [[NSUserDefaults standardUserDefaults] objectForKey:@"mutableArray_01"];
    if([whatIsThis isKindOfClass:[NSMutableArray class]])
    {
        NSLog(@"The array is mutable.");
        mutableArrayInCheck = (NSMutableArray *)whatIsThis;
    }
    if([whatIsThis isKindOfClass:[NSArray class]])
    {
        NSLog(@"The array is immutable.");
    }
    if ([whatIsThis isMemberOfClass:[NSMutableArray class]])
    {
        NSLog(@"The array is a member of NSMutableArray class");
    }

    if (mutableArrayInCheck) 
    {
        [mutableArrayInCheck addObject:@"three"];
        NSLog([mutableArrayInCheck description]);
    }
}

Now, according to the apple documentation, one would expect the console to only display the immutable line. But when I execute the code, the following lines are displayed in the console:

2012-01-05 18:47:33.328 Tester_01[78533:f803] The array is mutable.
2012-01-05 18:47:33.348 Tester_01[78533:f803] The array is immutable.
2012-01-05 18:47:33.349 Tester_01[78533:f803] (
    one,
    two,
    three
)

So, I am wondering if there is something that I am missing here.

For additional information, the code that executes the tests is as shown:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    BOOL setupKey = NO;
    if (setupKey) 
    {
        [self setupTest];
    }   
    BOOL checkKey = YES;
    if (checkKey)
    {
        [self checkTest];
    }

    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

Initially, I ran the project with setupKey set to YES. After the first run, I changed the setupKey to NO. The console log is an outcome whilst the setupKey was set to NO. Let me know what you think.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

海的爱人是光 2025-01-01 08:11:35

严格来说你是对的。 “返回的值是不可变的”这一说法令人困惑,因为这使得获取可变对象看起来应该不可能。但是,该语句应理解为“不能保证返回的值是可变的”。因此,即使你存储一个可变数组,当你读回该值时,你也会得到一个 NSArray 对象(它可能是可变后代类 NSMutableArray 的对象,但这不能保证,并且可能在运行之间有所不同或取决于数组内容)。

Strictly speaking you are right. The statement "Values returned are immutable" is confusing, because this makes it look like getting a mutable object should be impossible. However, the statement should be read as "Values returned cannot be guaranteed to be mutable". So, even if you store a mutable array, when you read the value back, you will get a NSArray object (which might be an object of the mutable descendent class NSMutableArray, but this cannot be guaranteed and may vary between runs or depend on the array content).

小帐篷 2025-01-01 08:11:35

isKindOfClass 该方法不适合类簇,

下一段位于文档中

在对类簇表示的对象使用此方法时要小心。由于类簇的性质,您返回的对象可能并不总是您期望的类型。如果您调用返回类簇的方法,则该方法返回的确切类型是您可以对该对象执行的操作的最佳指示。例如,如果一个方法返回一个指向 NSArray 对象的指针,则不应使用此方法来查看该数组是否可变,如以下代码所示:

 // DO NOT DO THIS!
 //if ([myArray isKindOfClass:[NSMutableArray class]])
 //{
 // Modify the object
 //}

isKindOfClass the method is not appropriate for the class cluster

the next paragraph is in the documentation

Be careful when using this method on objects represented by a class cluster. Because of the nature of class clusters, the object you get back may not always be the type you expected. If you call a method that returns a class cluster, the exact type returned by the method is the best indicator of what you can do with that object. For example, if a method returns a pointer to an NSArray object, you should not use this method to see if the array is mutable, as shown in the following code:

 // DO NOT DO THIS!
 //if ([myArray isKindOfClass:[NSMutableArray class]])
 //{
 // Modify the object
 //}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文