如何将 NSArray 中的对象添加到 NSMutableArray 的末尾?

Posted

技术标签:

【中文标题】如何将 NSArray 中的对象添加到 NSMutableArray 的末尾?【英文标题】:How to add objects from an NSArray to the end of an NSMutableArray? 【发布时间】:2012-03-17 15:44:48 【问题描述】:

所以我需要添加用户使用 NSOpenPanel 选择的 NSArray 中的对象,并将所有文件名放入该数组中。然后我有一个名为 arguments 的 NSMutableArray,我以编程方式放置参数。然后我需要将这些对象从 NSArray 添加到这个 NSMutableArray 的末尾。所以我使用[NSMutableArray addObjectsFromArray:NSArray],这一直给我一个错误。

这就是我对代码所做的: AppDelegate.h

#import <Cocoa/Cocoa.h>

@interface ZipLockAppDelegate : NSObject <NSApplicationDelegate> 
    IBOutlet NSTextField *input;
    IBOutlet NSTextField *output;
    IBOutlet NSTextField *password;
    NSArray *filenames;
    NSMutableArray *arguments;
    NSArray *argumentsFinal;


@property (assign) IBOutlet NSWindow *window;
@property (retain) NSArray *filenames;
@property (copy) NSMutableArray *arguments;

- (IBAction)chooseInput:(id)sender;
- (IBAction)chooseOutput:(id)sender;
- (IBAction)createZip:(id)sender;

@end

AppDelegate.m

#import "ZipLockAppDelegate.h"

@implementation ZipLockAppDelegate

@synthesize window = _window;
@synthesize filenames;
@synthesize arguments;

- (IBAction)chooseInput:(id)sender 
    NSOpenPanel *openZip = [[NSOpenPanel alloc] init];
    [openZip setCanChooseFiles:YES];
    [openZip setCanChooseDirectories:YES];
    [openZip setCanCreateDirectories:NO];
    [openZip setAllowsMultipleSelection:YES];
    [openZip setTitle:@"Select All Files/Folders to be zipped"];
    int result = [openZip runModal];
    if (result == 1) 
        filenames = [openZip filenames];
    


- (IBAction)createZip:(id)sender 
    [progress startAnimation:self];
    arguments = [NSMutableArray arrayWithObjects:@"-P", [password stringValue], [output stringValue], nil];
    [self.arguments addObjectsFromArray:filenames];
    argumentsFinal = [[NSArray alloc] initWithArray:self.arguments];
    NSTask *makeZip = [[NSTask alloc] init];
    [makeZip setLaunchPath:@"/usr/bin/zip"];
    [makeZip setArguments:argumentsFinal];
    [makeZip launch];
    [makeZip waitUntilExit];
    [progress stopAnimation:self];

这是我在日志中不断出现的错误。我不知道为什么我会得到这个。

EXC_BAD_ACCESS(code=13,address=0x0)

这指向[arguments addObjectsFromArray:filenames];这一行

我只能弄清楚关于选择器和实例的第一部分,但我不知道它是什么意思。帮助...

【问题讨论】:

设置数组时应该使用-mutableCopy,而不是-copy。你在使用 ARC 吗? addObjectsFromArray: 是将另一个数组中的对象添加到可变数组末尾的正确方法。另外,argumentsFinal 是不必要的;每个 NSMutableArray 都是一个 NSArray,因此您可以使用 self.arguments 作为任务的参数。 【参考方案1】:

保持一致。首先,all 为您的实例变量添加下划线前缀,而不仅仅是其中的一些。

 // Change this...
@synthesize window = _window;
@synthesize filenames;
@synthesize arguments;

//...to this
@synthesize window = _window;
@synthesize filenames = _filenames;
@synthesize arguments = _arguments;

那你就不能再这样做了:

arguments = [NSMutableArray arrayWithObjects:@"-P", [password stringValue], [output stringValue], nil];

请注意,在下一行,您正在执行以下操作:

[self.arguments addObjectsFromArray:filenames];

同样,在使用属性而不是直接访问实例变量时保持一致将帮助您避免此类错误。所以重写上一行来使用该属性,像这样:

self.arguments = [NSMutableArray arrayWithObjects:@"-P", [password stringValue], [output stringValue], nil];

编译器将self.arguments = someArg 翻译成[self setArguments:someArg]。在这种情况下,需要 setter 方法来保留对象,以便在引用仍存储在 _arguments 实例变量中时不会释放它。

【讨论】:

我假设 window=_window 是模板代码,其余的都是添加的。 谢谢你这工作。保持一致确实有助于 self.arguments【参考方案2】:

您是否尝试过调试它以查看文件名是否已初始化?查看您的崩溃日志,您正在引用一个 nil 指针。似乎文件名或参数从未初始化。

另外,尝试将参数数组设置为保留类型而不是复制。

您似乎也不断地来回参考您的参考资料。如果您不想继续输入 self.arguments,请在您的 synthesize 语句中创建一个 ivar 并坚持下去。

@synthesize filenames = _filenames;
@synthesize arguments = _arguments;

[_arguments addObjectsFromArray:_filenames];

【讨论】:

ivar 是通过综合是否指定另一个名称来创建的。默认与属性同名; @synthesize arguments; 创建 -(NSMutableArray *)arguments-(void)setArguments:(NSMutableArray *)newArguments 和一个名为 arguments 的 ivar。【参考方案3】:

您的arguments 对象是NSArray,而不是NSMutableArray。根据定义,您只能将对象添加到可变数组。试试这个:

arguments = [NSMutableArray arrayWithObjects:@"-P", [password stringValue], [output stringValue], nil];

【讨论】:

谢谢你解决了这个问题,但现在我有了一个新问题。现在我的应用程序崩溃并给了我EXC_BAD_ACCESS(code=13, address=0x0) 并指向[self.arguments addObjectsFromArray:filenames]; 行,我不知道出了什么问题 我假设 chooseInput: 在调用 createZip 之前执行?你在用ARC吗?如果没有,那么您可能必须在选择输入中保留文件名:. 我没有使用 ARC,我保留了它

以上是关于如何将 NSArray 中的对象添加到 NSMutableArray 的末尾?的主要内容,如果未能解决你的问题,请参考以下文章

如何将自定义对象的 NSArray 归档到 Objective-C 中的文件

如何将一个 NSArray 的两个不同索引处的对象存储到另一个 NSArray 的一个索引

NSArray 中的 NSObject 的属性是不是会发生变化,或者是不是必须再次将它们添加到 NSArray?

如何将变量与 NSArray 中的 NSDictionary 中的对象进行比较?

如何将字典的 NSDictionary 添加到 NSArray?

如何在 NSArray 的第一个索引处添加对象