2012-12-12 5 views
1

몇 가지 매개 변수가 필요한 일반 루틴이 있습니다. 뭔가 같은 :Objective-C - 콜백 매개 변수가있는 블록 저장

-(id) doStuff:(int)A:(int)B:(int)C { 
    //doStuff 
    return object; 
} 

나는 자신의 ID와 사용자 정의 세포의 숫자를 수납하는 UITableViewController, 각이있다. '저장'을 누르면 해당 셀이 반복되고 일부 셀은 저장 될 때 '추가 동작'이 필요합니다.

지금까지 NSString * 및 사용자 지정 셀에 대리인을 저장하는 '콜백'개체를 만들었습니다. '저장'을 존재하면, 셀이 적용 어떤 콜백을 가지고 있으며, 어느 정도 잘 작동

SEL sel = NSSelectorFromString(Sel); 
if([Del respondsToSelector:sel]) 
    [Del performSelector:sel withObject:Cell]; 

지금 사용 여부, 보이는 ...하지만, 내가에 스위치/사건을 어떻게 전달할 방법이 필요 전달 된 셀의 ID입니다.이를 피하고 싶습니다.

그래서 대신 블록을 사용하고 싶습니다. 그러나 매개 변수가있는 블록을 변수에 저장하는 방법을 알지 못합니다.

것은 내가 할 노력하고있어 무엇 :

은 기능 블록 doStuff를 선언합니다.

id (^doStuff) (int, int, int) = ^(int A, int B, int C) { 
    //does Stuff 
}; 

그리고 콜백

[Cell addCallback:(^doStuff)(1, 2, 3)]; 

블록은 그 순간에 호출하지만, 셀에 저장하고 적절한시기에만를 호출 할 수 없습니다해야하기 때문에 이전에 생성 된 블록을 추가합니다. 어떻게하면이 문제를 올바르게 해결할 수 있습니까?

대단히 감사합니다.

편집 : 내가 피하고 싶은 것은 셀에 불필요하게 특수화해야하기 때문에 셀에 매개 변수를 저장하고 호출 할 때 전달하는 것입니다.

그것은 당신이 원하는 것을 같은 소리

답변

1

이처럼 블록, 뭔가를 호출하는 블록 :

[cell addCallback:^{ doStuff(1, 2, 3); }]; 

을 그러나 이것은 약간 이상하고 복잡한 디자인이다. 단 하나의 블록 만 쓰는 방법이있을 것 같지만 자신이하는 일에 대해 더 잘 알지 못하면 특정 솔루션을 제공하기가 어렵습니다.

+0

나는 거의 내가하려고하는 것을 요약 한 것 같다. 이상하게 들릴지 모르지만 블록은 그렇습니다. 나는 그것을 시도하고 당신에게 피드백을 줄 것이다. 고마워요 :) – ATaylor

0

가장 직접적인 방법은 블록 매개 변수의 모양을 포함하는 typedef를 만든 다음이를 사용하여 새 속성/ivar을 선언하는 것입니다.다음 샘플 코드는 분별있는 TableView 프레임 워크 SCCellActions 클래스에서 복사 다음과 같이 유사

cellActions.willDisplay = ^(SCTableViewCell *cell, NSIndexPath *indexPath) 
{ 
    cell.backgroundColor = [UIColor yellowColor]; 
}; 

, 당신은 매개 변수를 선언 할 수있다 : 다음과 같이

typedef void(^SCCellAction_Block)(SCTableViewCell *cell, NSIndexPath *indexPath); 

@interface SCCellActions : NSObject 
... 
@property (nonatomic, copy) SCCellAction_Block willDisplay; 
... 
@end 

당신은 다음 속성을 설정할 수 있습니다

... 
- (void)callActionBlock:(SCCellAction_Block actionBlock) 
{ 
    if(actionBlock) 
    { 
     actionBlock(self.cell, self.cellIndexPath); 
    } 
} 
... 

이 경우 메서드는 다음과 같이 호출해야합니다.

[myObject callActionBlock:^(SCTableViewCell *cell, NSIndexPath *indexPath {cell.backgroundColor = [UIColor yellowColor];}]; 
+0

아니, 나는 그것이 내가 찾고있는 것 같지 않아. 알다시피,이 설정은 셀을 더 전문화하거나 ID와 일치하는 매개 변수를 결정하기 위해 스위치 케이스로 이동해야합니다. 어쨌든 고마워. – ATaylor

0

이 답변은 Chuck의 제안에 기반을두고 있으며, 실현에 직면 한 함정에 대해 설명합니다.

생성 :

Cell = [self CreateCell]; 
[Cell addCallback:^{ return doStuff(Cell, 1, 2, 3, 4) } At:ON_SAVE]; 

doStuff는 세포 선언하기 전에 로컬 블록이다. 블록 안에 호출 셀에 대한 참조가 필요했기 때문에 셀에 직접 추가 할 수 없었습니다.

이 시점에서 핏방울 : 클래스 변수. 블록은 로컬 변수 만 ... 또는 오히려 '복사'하지만 클래스 변수는 유지하지 않습니다. 'Cell'이 클래스 변수이고 'CreateCell'에 의해 설정되었다고 가정하면 블록은 블록 실행시 Cell 값으로 작동합니다.

이와 같이, 필요한 경우 클래스 변수의 값을 가정하는 로컬 변수를 선언하는 것을 기억하는 것이 중요합니다.

저장 :이 시점에서

- (void) addCallback:(CallBlock_t)B At:(int)at { 
    //Creates a Callback-Object and passes it the block and adds it to an Array. 
} 

- (id) initWithBlock:(CallBlock_t)B At:(int)at { 
    self = [super init]; 
    if(self) { 
     Block = [B copy]; //Yes, Copy. Not retain. 
     When = at; 
    } 
    return self; 
} 

함정 : 블록이 단순히 유지하는 경우, 호출 함수에서 로컬 블록이 범위를 벗어나 이동하고 프로그램이 '나쁜 액세스'와 함께 실패합니다. 복사하면이 문제가 해결됩니다.

물론 블록 사용을 마친 후에는 (콜백 클래스의 dealloc에서) 블록을 해제해야하지만 주어진 것입니다.

이 작은 설명이 누군가에게 슬픔을 덜어주기를 바랍니다.