![](/img/trans.png)
[英]Why does [NSMutableString stringWithString:@“”] work?
[英]Why does my NSMutableString edit sometimes not work?
我正在嘗試修復一些編號錯誤的電影字幕文件(每個子字幕由空行分隔)。 以下代碼掃描到測試文件中錯誤的字幕索引號。 如果我只是“打印”有故障的舊索引並替換新索引,一切都會按預期顯示。
//######################################################################
-(IBAction)scanToSubIndex:(id)sender
{
NSMutableString* tempString = [[NSMutableString alloc] initWithString:[theTextView string]];
int textLen = (int)[tempString length];
NSScanner *theScanner = [NSScanner scannerWithString:tempString];
while ([theScanner isAtEnd] == NO)
{
[theScanner scanUpToString:@"\r\n\r\n" intoString:NULL];
[theScanner scanString:@"\r\n\r\n" intoString:NULL];
if([theScanner scanLocation] >= textLen)
break;
else
{ // remove OLD subtitle index...
NSString *oldNumStr;
[theScanner scanUpToString:@"\r\n" intoString:&oldNumStr];
printf("old number:%s\n", [oldNumStr UTF8String]);
NSRange range = [tempString rangeOfString:oldNumStr];
[tempString deleteCharactersInRange:range];
// ...and insert SEQUENTIAL index
NSString *newNumStr = [self changeSubIndex];
printf("new number:%s\n\n", [newNumStr UTF8String]);
[tempString insertString:newNumStr atIndex:range.location];
}
}
printf("\ntempString\n\n:%s\n", [tempString UTF8String]);
}
//######################################################################
-(NSString*)changeSubIndex
{
static int newIndex = 1;
// convert int to string and return...
NSString *numString = [NSString stringWithFormat:@"%d", newIndex];
++newIndex;
return numString;
}
但是,當我嘗試將新索引寫入靜音字符串時,最終會得到如下無序的結果:
sub 1
sub 2
sub 3
sub 1
sub 5
sub 6
sub 7
sub 5
sub 9
sub 7
sub 8
一個有趣的觀察結果(和可能的線索?)是,當我達到字幕編號 1000時,每個數字都會根據需要按順序寫入可變字符串。 我已經為此苦苦掙扎了幾個星期,而且我在 SO 上找不到任何其他類似的問題。 非常感謝任何幫助:-)
NSMutableString
是NSString
的子類。 換句話說,您可以在需要NSString
的地方傳遞NSMutableString
。 但這並不意味着您可以修改它。
scannerWithString:
需要NSString
。 翻譯成人類語言 - 我期望一個字符串,我也期望該字符串是只讀的(不會被修改)。
換句話說 - 你的代碼被認為是程序員錯誤 - 你給NSScanner
一些東西, NSScanner
期望不可變的字符串,你正在修改它。
我們不知道NSScanner
class 在幕后做什么。 可以有緩沖或任何其他類型的優化。
即使您對提到的scanLocation
修復(在評論中)很幸運,您也不應該依賴它,因為引擎蓋下的實現可能會隨着任何新版本而改變。
不要這樣做。 不僅在這里,而且在您看到不可變數據類型的任何地方。
(在某些情況下您可以做到這一點,但是您應該真正知道幕后實現在做什么,確保它不會被修改等。但一般來說,除非您知道自己在做什么,否則這不是一個好主意'正在做。)
此示例代碼基於以下假設:
@"\r\n"
)@import Foundation;
NS_ASSUME_NONNULL_BEGIN
@interface SubRipText : NSObject
+ (NSString *)fixSubtitleIndexes:(NSString *)string;
@end
NS_ASSUME_NONNULL_END
@implementation SubRipText
+ (NSString *)fixSubtitleIndexes:(NSString *)string {
NSMutableString *result = [@"" mutableCopy];
__block BOOL nextLineIsIndex = YES;
__block NSUInteger index = 1;
[string enumerateLinesUsingBlock:^(NSString * _Nonnull line, BOOL * _Nonnull stop) {
if (nextLineIsIndex) {
[result appendFormat:@"%lu\r\n", (unsigned long)index];
index++;
nextLineIsIndex = NO;
return;
}
[result appendFormat:@"%@\r\n", line];
nextLineIsIndex = line.length == 0;
}];
return result;
}
@end
用法:
NSString *test = @"29\r\n"
"00:00:00,498 --> 00:00:02,827\r\n"
"Hallo\r\n"
"\r\n"
"4023\r\n"
"00:00:02,827 --> 00:00:06,383\r\n"
"This is two lines,\r\n"
"subtitles rocks!\r\n"
"\r\n"
"1234\r\n"
"00:00:06,383 --> 00:00:09,427\r\n"
"Maybe not,\r\n"
"just learn English :)\r\n";
NSString *result = [SubRipText fixSubtitleIndexes:test];
NSLog(@"%@", result);
Output:
1
00:00:00,498 --> 00:00:02,827
Hallo
2
00:00:02,827 --> 00:00:06,383
This is two lines,
subtitles rocks!
3
00:00:06,383 --> 00:00:09,427
Maybe not,
just learn English :)
還有其他方法可以實現這一點,但您應該考慮可讀性、寫入速度、運行速度……取決於您的使用情況——您要修復其中的多少,等等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.