2015-11-13 3 views
0

Следующий код записываются в Swift 2.0, чтобы создать массив dispatch_block_tКак реализовать copyWithZone в Swift 2.0?

let a: dispatch_block_t = { 
    self.pickImages() 
} 
let b: dispatch_block_t = { 
    self.takePicture() 
} 
let c: dispatch_block_t = { 
    self.pickVideos() 
} 
let d: dispatch_block_t = { 
    self.shootVideo() 
} 
let e: dispatch_block_t = { 
    self.recordAudio() 
} 
let f: dispatch_block_t = { 
    self.closeView() 
} 

let block1 = Block(block: a) 
let block2 = Block(block: b) 
let block3 = Block(block: c) 
let block4 = Block(block: d) 
let block5 = Block(block: e) 
let block6 = Block(block: f) 

let actionsArray: NSArray = [block1, block2, block3, block4, block5, block6] 

А определен Block класса следующим образом,

class Block: NSObject, NSCopying { 
    var block: dispatch_block_t 

    init(block: dispatch_block_t){ 
     self.block = block 
    } 

    func copyWithZone(zone: NSZone) -> AnyObject { 
     return self.block as! AnyObject 
    } 
} 

я мог бы создать массив dispatch_block_t с выше куском кода. Но мне нужно передать этот массив как параметр в другую функцию, и перед этим массивом я столкнулся с проблемой.

Я зову эту функцию в случае нажатия кнопки,

menuView = btSimplePopUP(itemImage: imgs as [AnyObject], 
    andTitles: titles as [AnyObject], 
    andActionArray: actionsArray as [AnyObject], 
    addToViewController: self) 

И я получаю сообщение об ошибке, когда следующий фрагмент выполняется,

- (instancetype)initWithImage:(UIImage *)image title:(NSString *)title action:(dispatch_block_t)action { 
if ((self = [super init])) { 
    _title = [title copy]; 
    _imageView = [[UIImageView alloc]initWithImage:image]; 
    _action = [action copy]; 
} 

return self; 
} 

И ошибка,

Не удалось отличить значение типа '() ->()' (0x15164018) от 'Swift.AnyObject' (0x101e500c).

Я получаю эту ошибку в copyWithZone Функция Block класс.

Полный исходный код btSimplePopUp можно посмотреть здесь, https://github.com/balram3429/btSimplePopUp/blob/master/btSimplePopUp/btSimplePopUP.m

+0

вы задали тот же вопрос в третий раз, что ошибка у которой сталкиваются при конверсии или тип cast –

+0

Раньше я не мог создайте массив dispatch_block_t. Но теперь я создал массив. Но я не мог обработать его в функции, определенной в другом классе. –

+0

'*** NSForwarding: warning: object 0x7a5841b0 класса 'ProjName.Block' не реализует методSignatureForSelector: - проблема впереди Unrecognized selector - [ProjName.Block copy]' Я получил эту ошибку перед определением функции 'copyWithZone' в' Block'. После определения этого параметра я получаю следующую ошибку: 'Невозможно передать значение типа '() ->()' (0x15164018) в 'Swift.AnyObject' (0x101e500c) .'. У вас есть идея решить эту проблему? –

ответ

1

dispatch_block_t является структурой, не является объектом. На самом деле это C-структура. Я не понимаю, почему вам нужно использовать dispatch_block_t, почему бы просто не закрыть закрытие. Если вы должны передать его функции dispatch_, оберните ее в dispatch_block_t на сайте вызова.

Для этого Swiftify:

В Swift, dispatch_block_t это просто псевдоним для () ->() т.е. функция пустот/закрытия возвращения Void. Таким образом, вы можете просто сказать

let a = { self.pickImages() } 
// etc 

let actionArray = [ a, b, c, ...] 

Однако pickImages это функция, которая имеет тот же тип (технически это выделанной над self, но не беспокойтесь о том, что это значит), так что вы можете забыть о а, б, с немного и просто сделать это

let actionArray = [ self.pickImages, self.takePhoto, ... ] 

и Swift, вы можете использовать один из «объектов» в этом массиве в любое время у вас есть параметр, который принимает dispatch_block_t например,

dispatch_after(someTime, dispatch_get_main_queue(), actionArray[0]) 
+0

Спасибо за ваш ответ. Я новичок в iOS. Можете ли вы отправить какой-нибудь образец кода, чтобы пройти закрытие? –

+0

@DeepikaMasilamani добавил код для вас – JeremyP

+0

[Документация Apple говорит] (https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/), что 'dispatch_block_t' является typedef для' void (^) (недействительный) '. Это означает, что он ** является ** объектом. (что означает, что это также структура C, но это не так, что это «не объект».) –

0

Необходимо изменить рамки Objc. ваш btSimplePopUP должен работать как ActionContainer из этого примера. ActionObject - это вставка версии Swift dispatch_block_t. Как распаковать его в свой код? См. Функцию задания ActionContainer.

// 
// Actions.h 
// test 
// 


#ifndef Actions_h 
#define Actions_h 
#import <Foundation/Foundation.h> 

@interface ActionObject : NSObject 
@property (nonatomic, copy) dispatch_block_t action; 
@end 


@interface ActionContainer : NSObject 
@property NSArray * actions; 
-(void)job; 
@end 

#endif /* Actions_h */ 

...

// 
// Actions.m 
// test 
// 


#import <Foundation/Foundation.h> 
#import "Actions.h" 


@implementation ActionObject 

-(instancetype)initWithAction: (dispatch_block_t)someaction { 
    if ((self = [super init])) { 
     _action = [someaction copy]; 
    } 
    return self; 
} 

@end 

@implementation ActionContainer 
-(void)job { 
    if (_actions != nil) { 
     NSUInteger count = _actions.count; 
     NSUInteger i; 
     for (i = 0; i < count; i++) { 
      ActionObject *action = _actions[i]; 
      action.action(); 
     } 

    } 
} 

@end 

...

// 
// Use this file to import your target's public headers that you would like to expose to Swift. 
// 

#import "Actions.h" 

...

// 
// main.swift 
// test 
// 


import Foundation 

let a = ActionObject() 
a.action = { 
    print("swift a action") 
} 
let b = ActionObject() 
b.action = { 
    print("swift b action") 
} 
let arr: NSArray = [a,b] 

let actions = ActionContainer() 
actions.actions = arr as [AnyObject] 
actions.job() 

продукции

swift a action 
swift b action 
Program ended with exit code: 0 

...

@implementation ActionContainer 
-(void)job { 
    if (_actions != nil) { 
     NSUInteger count = _actions.count; 
     NSUInteger i; 
     for (i = 0; i < count; i++) { 
      ActionObject *action = _actions[i]; 
      // myAction is 'unboxed' swift block 
      // you can save it, run it 
      // somwhere in you ObjectiveC code 
      dispatch_block_t myAction = action.action; 
      // run it 
      myAction(); 
     } 

    } 
} 
+0

@Deepica Masilamani, если у вас еще нет идеи о том, как изменить собственный код, опубликовать весь проект на github, я могу попробуйте изменить его для вас. нет необходимости задавать один и тот же вопрос снова и снова. нет возможности бросить swatch dispatch_block_t как AnyObject. – user3441734

+0

Я постараюсь заставить его работать, если я не могу, я опубликую свой проект в git. Спасибо за вашу помощь @ user3441734 –

+0

action.action() просто запустите его (чтобы продемонстрировать его функциональность). значение - action.action. вы можете сохранить его для дальнейшего использования в действии свойства btPopUpItem – user3441734

 Смежные вопросы

  • Нет связанных вопросов^_^