objective-c stringByAppendingPathComponent,它是如何工作的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1489522/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 22:16:19  来源:igfitidea点击:

stringByAppendingPathComponent, hows it work?

objective-ccocoa

提问by fuzzygoat

EDIT_v002

编辑_v002

I have had a look at all the comments and I am starting to see what I should be doing. To that end I have modified my code (see below) I have changed newPath to a NSString, removed the [[alloc] init] and the end [release] as its now handled by the system. I am using stringByAppendingPathComponent, letting it add a separator between rootPath and fileName before its assigned to the NSString. It does work, and I ran it through the static analyser with no problems.

我看了所有的评论,我开始明白我应该做什么。为此,我修改了我的代码(见下文),我将 newPath 更改为 NSString,删除了 [[alloc] init] 和结尾 [release],因为它现在由系统处理。我正在使用 stringByAppendingPathComponent,让它在分配给 NSString 之前在 rootPath 和 fileName 之间添加一个分隔符。它确实有效,我通过静态分析器运行它没有任何问题。

// ------------------------------------------------------------------- **
// DISC: FILEWALKER ..... (cocoa_fileWalker.m)
// DESC: List all "*.png" files in specified directory
// ------------------------------------------------------------------- **
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSString *fileName;
    NSDictionary *attrDir;
    NSError *myError;
    NSNumber *fileSize;
    NSFileManager *manager = [NSFileManager defaultManager];
    NSString *rootPath = [@"~/Pictures/Ren/PRMan" stringByExpandingTildeInPath];
    NSString *newPath;

    NSLog(@"Home: %@",rootPath);

    for(fileName in [manager enumeratorAtPath:rootPath]){
        if ([[fileName pathExtension] isEqual:@"png"]) {    

            newPath = [rootPath stringByAppendingPathComponent:fileName];   
            attrDir = [manager attributesOfItemAtPath:newPath error:&myError];
            fileSize = [attrDir objectForKey: @"NSFileSize"];
            NSLog(@"File: %@ Size: %@", newPath, fileSize);
        }
    }
    [pool drain];
    return 0;
}
// ------------------------------------------------------------------- **

gary

加里

回答by Peter Hosey

stringByAppendingPathComponent, hows it work?

stringByAppendingPathComponent,它是如何工作的?

Simple. You want to append a path component. You send that message to the string you want to append a path component to, passing the path component you want to append.

简单的。您想附加一个路径组件。您将该消息发送到要将路径组件附加到的字符串,传递要附加的路径组件。

Path components are not the slashes; if they were, the pathComponentsmethod would return nothing but an array of slashes. Path components are the parts betweenthe slashes (although there is a special case, described in the definition of pathComponents).

路径组件不是斜线;如果是,该pathComponents方法将只返回一个斜杠数组。路径组件是斜线之间的部分(尽管有一种特殊情况,在 的定义中进行了描述pathComponents)。

The slash is the path separator. This is hard-coded inside of Cocoa; it's currently (and likely to always be) a slash. So, if you really wanted to append a slash to a string, the most likely reason would be that you want to append a path separator, not a path component.

斜线是路径分隔符。这是 Cocoa 内部的硬编码;它目前(并且可能永远是)是斜线。因此,如果您真的想向字符串附加斜杠,最可能的原因是您想要附加路径分隔符,而不是路径组件

    [newPath setString:rootPath];
    [newPath appendString:@"/"];
    [newPath appendString:fileName];
    [newPath setString:rootPath];
    [newPath appendString:@"/"];
    [newPath appendString:fileName];

fileNameis the component you want to add. Use stringByAppendingPathComponent:and pass fileName, not a slash.

fileName是您要添加的组件。使用stringByAppendingPathComponent:并通过fileName,而不是斜线。

As for whether your example leaks: Well, does an object fall out of scope without getting released? The answer to that question is the answer to whether it's a leak. If you're not sure, review the memory management rules.

至于您的示例是否泄漏:那么,对象是否会在没有被释放的情况下超出范围?这个问题的答案是它是否是泄漏的答案。如果您不确定,请查看内存管理规则

回答by nall

You don't append the delimiter. You append the next path component (eg filename, dir, etc). This avoids you needing to know the delimiter for your particular system.

您不附加分隔符。您附加下一个路径组件(例如文件名、目录等)。这避免了您需要知道特定系统的分隔符。

NSMutableString* mutablePath = [NSMutableString string];
NSString* fullPath = [rootPath stringByAppendingPathComponent:filename];

[mutablePath setString:fullPath]; // OK to setString: of Mutable with non-Mutable
[mutablePath appendString:someOtherString]; // This won't cause an exception

// Example to clarify on comments below
{
    // This will cause a compiler warning.
    // warning: incompatible Objective-C types assigning
    //    ‘struct NSString *', expected ‘struct NSMutableString *'
    NSMutableString* ms = [@"FOO" stringByAppendingPathComponent:@"BAR"];
}

There is a fairly clear example in the documentation.

文档中有一个相当清晰的例子

回答by Quinn Taylor

All the existing answers are leaking the original testPathstring. For something as simple as this, why has nobody recommended -[NSMutableString appendString:]intead?

所有现有答案都泄漏了原始testPath字符串。对于这么简单的事情,为什么没有人推荐-[NSMutableString appendString:]呢?

[testPath appendString:@"/"];

There's no equivalent to -stringByAppendingPathComponent:for NSMutableString, but it looks like he's just trying to add a slash, not a path component anyway. If you really wanted to add a path component, you could do this:

没有与-stringByAppendingPathComponent:NSMutableString的等价物,但看起来他只是想添加一个斜杠,而不是路径组件。如果你真的想添加一个路径组件,你可以这样做:

[testPath setString:[testPath stringByAppendingPathComponent:@"..."]];

It's an annoying workaround, but as @dreamlax points out, -stringByAppendingPathComponent:always returns an immutable string, even when called on an NSMutableString object. :-(

这是一个烦人的解决方法,但正如@dreamlax 指出的那样-stringByAppendingPathComponent:,即使在 NSMutableString 对象上调用时,它也始终返回一个不可变的字符串。:-(

回答by dreamlax

-stringByAppendingPathComponentreturns a new immutable string, it doesn't modify the original. You have to use the return value of this method.

-stringByAppendingPathComponent返回一个新的不可变字符串,它不会修改原始字符串。您必须使用此方法的返回值。

回答by André Hoffmann

The last line should be:

最后一行应该是:

testPath = [testPath stringByAppendingPathComponent:@"/"];

回答by ennuikiller

[testPath stringByAppendingString:@"/"]