【问题标题】:Inputstring is null after being set in a static method, why?输入字符串在静态方法中设置后为空,为什么?
【发布时间】:2012-10-02 10:50:42
【问题描述】:

我不确定在我的特定情况下如何管理内存...

我有两种方法:

+(NSMutableDictionary *)loadPlist: (NSString*) name
                     andErrorDesc: (NSString*) errorDesc
                        andFormat: (NSPropertyListFormat*) format
                     andplistPath: (NSMutableString*) plistPath
{    
    NSString * destPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

    destPath = [destPath stringByAppendingPathComponent:
                 [NSString stringWithFormat:@"%@.plist", name]];

    if (![[NSFileManager defaultManager] fileExistsAtPath:destPath])
    {
        [[NSFileManager defaultManager] copyItemAtPath:[[NSBundle mainBundle] pathForResource:name ofType:@"plist"] toPath:destPath error:nil];
    }

    plistPath = [NSMutableString stringWithString:[destPath copy]];

    NSData * plistXML =
    [[NSFileManager defaultManager] contentsAtPath:plistPath];

    NSLog(@"AFTER plistPath: \n%@",plistPath);


    return
    (NSMutableDictionary *)[NSPropertyListSerialization
                            propertyListFromData:plistXML
                            mutabilityOption:NSPropertyListMutableContainersAndLeaves
                            format:format
                            errorDescription:&errorDesc];
}


+(bool)writeToCache:(NSString*) data andField: (NSString*) field
{
    NSString * errorDesc = nil;
    NSPropertyListFormat format;
    NSMutableString * plistPath;
    NSMutableDictionary * temp = [BPUtils loadPlist:@"cache" andErrorDesc:errorDesc andFormat:&format andplistPath:plistPath];

    if (!temp)
    {
        NSLog(@"Error reading plist: %@, format: %d", errorDesc, format);
        return false;
    }

    NSMutableArray * arr = [temp objectForKey:field];
    [arr addObject:data];

    NSLog(@"path: %@",plistPath);

    // Write to plist
    bool res = [temp writeToFile:plistPath atomically:YES];

    NSLog(@"RES: %d", res);

    return true;
}

问题是在“plistPath”中发送到上述方法的底部方法在上述方法设置后检索了一个空的plistPath。为什么以及如何解决这个问题?

NSLog(@"path: %@",plistPath); 

在底部方法中显示null,为什么?

我使用 ARC。 还设置了“destPath”并显示了正确的路径。

【问题讨论】:

    标签: objective-c cocoa nsstring static-methods


    【解决方案1】:

    我相信你在这里可能会有点困惑。

    您正在底部方法中创建plistPath。然后你将plistPath 传递给

         [BPUtils loadPlist:@"cache" andErrorDesc:errorDesc andFormat:&format andplistPath:plistPath];
    

    plistPathNULL

         NSMutableString * plistPath; // Is NULL
    

    但是一旦它在本地通过plistPath 就会接管。

    +(NSMutableDictionary *)loadPlist: (NSString*) name
                     andErrorDesc: (NSString*) errorDesc
                        andFormat: (NSPropertyListFormat*) format
                     andplistPath: (NSMutableString*) plistPath // Notice the local plistPath variable. This is the one you are playing with in this method.
    

    此时您正在设置plistPath,但请记住它仍然只是一个局部变量而不是实例变量。所以按钮方法永远不会知道它被设置了,就按钮方法而言它仍然是NULL

    plistPath = [NSMutableString stringWithString:[destPath copy]];
    

    因此,无论您在顶部方法中的plistPath 中设置什么,都不会将其传递回底部方法,请认为顶部plistPath 在方法执行return 时被释放。 所以底部方法中的plistPath 将保持NULL

    所以试试这个解决方案

     static NSMutableString *yourNewStringforPlistPath; //This will be NULL
    
     +(NSMutableDictionary *)loadPlist: (NSString*) name
                     andErrorDesc: (NSString*) errorDesc
                        andFormat: (NSPropertyListFormat*) format
                     andplistPath: (NSMutableString*) plistPath
     {    
     NSString * destPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    
     destPath = [destPath stringByAppendingPathComponent:
                 [NSString stringWithFormat:@"%@.plist", name]];
    
     if (![[NSFileManager defaultManager] fileExistsAtPath:destPath])
     {
         [[NSFileManager defaultManager] copyItemAtPath:[[NSBundle mainBundle] pathForResource:name ofType:@"plist"] toPath:destPath error:nil];
     }
    
     yourNewStringforPlistPath = [NSMutableString stringWithString:[destPath copy]];
    
     NSData * plistXML =
     [[NSFileManager defaultManager] contentsAtPath:yourNewStringforPlistPath];
    
     NSLog(@"AFTER plistPath: \n%@",yourNewStringforPlistPath);
    
    
     return
     (NSMutableDictionary *)[NSPropertyListSerialization
                            propertyListFromData:plistXML
                            mutabilityOption:NSPropertyListMutableContainersAndLeaves
                            format:format
                            errorDescription:&errorDesc];
      }
    
    
      +(bool)writeToCache:(NSString*) data andField: (NSString*) field
      {
    NSString * errorDesc = nil;
    NSPropertyListFormat format;
    NSMutableDictionary * temp = [BPUtils loadPlist:@"cache" andErrorDesc:errorDesc andFormat:&format andplistPath:[NSNull null]]; // As this is already NULL you don't really need to pass yourNewStringforPlistPath in unless in the future this value can be set before this.
    
     if (!temp)
     {
        NSLog(@"Error reading plist: %@, format: %d", errorDesc, format);
        return false;
     }
    
      NSMutableArray * arr = [temp objectForKey:field];
     [arr addObject:data];
    
     NSLog(@"path: %@",yourNewStringforPlistPath);
    
     // Write to plist
     bool res = [temp writeToFile:yourNewStringforPlistPath atomically:YES];
    
     NSLog(@"RES: %d", res);
    
     return true;
     }
    

    【讨论】:

    • 这是因为方法是静态的吗?那么解决方案是什么?我希望能够在 top 方法中设置它,plistPath 也需要是静态的吗?
    • @hirre 查看解决方案。注意static NSMutableString *yourNewStringforPlistPath
    • 不要使用plistPath 这只会造成混乱。如果您使用plistPath 作为静态变量,则局部变量仍将覆盖静态变量。
    猜你喜欢
    • 1970-01-01
    • 2020-01-14
    • 1970-01-01
    • 2020-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-11
    相关资源
    最近更新 更多