iOS(Objective-C)。从数组中获取块时应用程序崩溃
iOS(Objective-C). Application crash when getting block from array
对 objective-c 中的块有疑问。
例如,我有一个动作列表。
我正在初始化一个块数组:
self.actions = @[
^() { [self showObject:self.object_1]; },
^() { [self showObject:self.object_2]; },
^() { [self showObject:self.object_3]; }
];
并在按下某行时调用它们:
- (void)pressedRowAtIndex:(NSInteger)index {
if (index < actions.count) {
void (^action)() = [actions objectAtIndex:index];
if (action != nil) {
action();
}
}
}
一切正常,没有问题。但是当我使用 initWithObjects
方法初始化我的动作数组时:
self.actions = [NSArray alloc] initWithObjects:
^() { [self showObject:self.object_1]; },
^() { [self showObject:self.object_2]; },
^() { [self showObject:self.object_3]; },
nil
];
然后我在尝试使用 NSArray
class 的 objectAtIndex
方法按索引执行操作时崩溃了 class。
我理解这个 inits 之间的区别。第一个不像第一个那样增加引用计数。但是有人可以解释为什么它会崩溃吗?
编辑:
我发现的一切。也许我很笨,其他地方是另一个有用的信息。
终端中没有崩溃信息:
Onik IV 代码:
小例子:
@interface ViewController () {
NSArray *actions;
}
@property (nonatomic, strong) NSString *object1;
@property (nonatomic, strong) NSString *object2;
@property (nonatomic, strong) NSString *object3;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
actions = [[NSArray alloc] initWithObjects:
^() { [self showObject:self.object1];},
^() { [self showObject:self.object2]; },
^() {[self showObject:self.object3]; },
nil];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.object1 = @"object 1";
self.object2 = @"object 2";
self.object3 = @"object 3";
void(^firsSimpleBlock)(void) = [actions lastObject];
firsSimpleBlock();
void(^simpleBlock)(void) = [actions firstObject];
simpleBlock();
}
-(void)showObject:(NSString *)object
{
NSLog(@"Show: %@",object);
}
@end
也是一样,你一定是有别的问题(sintax?)。
试试这个:
@interface ViewController ()
@property (nonatomic, strong) NSString *object1;
@property (nonatomic, strong) NSString *object2;
@property (nonatomic, strong) NSString *object3;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.object1 = @"object 1";
self.object2 = @"object 2";
self.object3 = @"object 3";
NSArray *actions = @[^() { [self showObject:self.object1];},
^() { [self showObject:self.object2]; },
^() {[self showObject:self.object3]; }
];
NSArray *secondActions = [[NSArray alloc] initWithObjects:
^() { [self showObject:self.object1];},
^() { [self showObject:self.object2]; },
^() { [self showObject:self.object3];},
nil
];
void(^firsSimpleBlock)(void) = [actions lastObject];
firsSimpleBlock();
void(^simpleBlock)(void) = [secondActions firstObject];
simpleBlock();
}
-(void)showObject:(NSString *)object
{
NSLog(@"Show: %@",object);
}
@end
尝试这样的事情。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
(^someBlock)(void) = ^void(void){
self.object1;
};
actions = [[NSArray alloc] initWithObjects:
[someBlock copy],
[someOtherBlock copy],
[anotherBlock copy],
nil];
}
块分配在堆栈上,因此当从堆栈中删除帧时,块将被删除,导致指向该块的所有指针的 sail 指针。当您分配带有文字“@”符号的 object 时,object 分配在池中,因此 "same" 的所有文字都指向同一实例并且永远不会被释放。
NSString *a = @"A";
NSString *b = @"A";
指向同一个字符串实例,而:
NSString *a = [NSString stringWithFormat:@"A"];
NSString *b = [NSString stringWithFormat:@"A"];
是两个不同的object。
因此它在您创建文字数组时有效,但是当您动态添加块时,它们将在需要使用它们时被删除,因此 BAD_ACCESS。解决方案是发送 "copy" 消息到块,该块将把它复制到堆中,块不会被释放。
对 objective-c 中的块有疑问。 例如,我有一个动作列表。 我正在初始化一个块数组:
self.actions = @[
^() { [self showObject:self.object_1]; },
^() { [self showObject:self.object_2]; },
^() { [self showObject:self.object_3]; }
];
并在按下某行时调用它们:
- (void)pressedRowAtIndex:(NSInteger)index {
if (index < actions.count) {
void (^action)() = [actions objectAtIndex:index];
if (action != nil) {
action();
}
}
}
一切正常,没有问题。但是当我使用 initWithObjects
方法初始化我的动作数组时:
self.actions = [NSArray alloc] initWithObjects:
^() { [self showObject:self.object_1]; },
^() { [self showObject:self.object_2]; },
^() { [self showObject:self.object_3]; },
nil
];
然后我在尝试使用 NSArray
class 的 objectAtIndex
方法按索引执行操作时崩溃了 class。
我理解这个 inits 之间的区别。第一个不像第一个那样增加引用计数。但是有人可以解释为什么它会崩溃吗?
编辑:
我发现的一切。也许我很笨,其他地方是另一个有用的信息。
终端中没有崩溃信息:
Onik IV 代码:
小例子:
@interface ViewController () {
NSArray *actions;
}
@property (nonatomic, strong) NSString *object1;
@property (nonatomic, strong) NSString *object2;
@property (nonatomic, strong) NSString *object3;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
actions = [[NSArray alloc] initWithObjects:
^() { [self showObject:self.object1];},
^() { [self showObject:self.object2]; },
^() {[self showObject:self.object3]; },
nil];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.object1 = @"object 1";
self.object2 = @"object 2";
self.object3 = @"object 3";
void(^firsSimpleBlock)(void) = [actions lastObject];
firsSimpleBlock();
void(^simpleBlock)(void) = [actions firstObject];
simpleBlock();
}
-(void)showObject:(NSString *)object
{
NSLog(@"Show: %@",object);
}
@end
也是一样,你一定是有别的问题(sintax?)。
试试这个:
@interface ViewController ()
@property (nonatomic, strong) NSString *object1;
@property (nonatomic, strong) NSString *object2;
@property (nonatomic, strong) NSString *object3;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.object1 = @"object 1";
self.object2 = @"object 2";
self.object3 = @"object 3";
NSArray *actions = @[^() { [self showObject:self.object1];},
^() { [self showObject:self.object2]; },
^() {[self showObject:self.object3]; }
];
NSArray *secondActions = [[NSArray alloc] initWithObjects:
^() { [self showObject:self.object1];},
^() { [self showObject:self.object2]; },
^() { [self showObject:self.object3];},
nil
];
void(^firsSimpleBlock)(void) = [actions lastObject];
firsSimpleBlock();
void(^simpleBlock)(void) = [secondActions firstObject];
simpleBlock();
}
-(void)showObject:(NSString *)object
{
NSLog(@"Show: %@",object);
}
@end
尝试这样的事情。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
(^someBlock)(void) = ^void(void){
self.object1;
};
actions = [[NSArray alloc] initWithObjects:
[someBlock copy],
[someOtherBlock copy],
[anotherBlock copy],
nil];
}
块分配在堆栈上,因此当从堆栈中删除帧时,块将被删除,导致指向该块的所有指针的 sail 指针。当您分配带有文字“@”符号的 object 时,object 分配在池中,因此 "same" 的所有文字都指向同一实例并且永远不会被释放。
NSString *a = @"A";
NSString *b = @"A";
指向同一个字符串实例,而:
NSString *a = [NSString stringWithFormat:@"A"];
NSString *b = [NSString stringWithFormat:@"A"];
是两个不同的object。
因此它在您创建文字数组时有效,但是当您动态添加块时,它们将在需要使用它们时被删除,因此 BAD_ACCESS。解决方案是发送 "copy" 消息到块,该块将把它复制到堆中,块不会被释放。