所以我需要添加用户使用NSOpenPanel选择的NSArray中的对象,并将所有文件名放入此数组中。然后我有一个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];
我只能弄清楚选择器和实例的第一部分,但我不知道它意味着什么。帮助...
答案 0 :(得分:1)
您的arguments
对象是NSArray
,而不是NSMutableArray
。根据定义,您只能将对象添加到可变数组中。试试这个:
arguments = [NSMutableArray arrayWithObjects:@"-P", [password stringValue], [output stringValue], nil];
答案 1 :(得分:1)
您是否尝试过调试它以查看文件名是否已初始化?查看您的崩溃日志,您将引用一个nil指针。似乎文件名或参数永远不会被初始化。
另外,尝试将arguments数组设置为retain类型而不是copy。
您似乎也会继续使用您的推荐信息。如果您不想继续键入self.arguments,请在您的合成语句中创建一个ivar并坚持使用。
@synthesize filenames = _filenames;
@synthesize arguments = _arguments;
[_arguments addObjectsFromArray:_filenames];
答案 2 :(得分: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
实例变量中时不会释放它。