0

다른 클래스에서 무언가가 일어 났을 때 뷰를 업데이트하려고하고 있는데,보기가 끝나면 델리게이트 또는 블록을 사용하여 콜백을 만드는 것이 가장 일반적인 방법 인 것으로 나타났습니다. 그러나 알림을 사용하여이 작업을 수행 할 수있었습니다. 내가 알고 싶은 것은 : 메소드 호출을 트리거하기 위해 알림을 사용하는 데 문제가 있습니까? 내가 모르는 어떤 위험이 있습니까? 알림을 통해 차단/위임을 사용하려는 이유가 있습니까?알림을 콜백으로 사용하는 데 문제가 있습니까?

저는 Objective-C를 처음 접해서, 제가 취하는 접근법이 올바른지 확신 할 수 없습니다.

예를 들어, ViewController에서 BLE 장치의 배터리 잔량을 설정하려고합니다. 주변 장치, 서비스/특성 등을 발견하는 BluetoothLEManager가 있습니다. 그러나 이렇게하려면 detailViewController에서 "연결"을 시작한 다음 찾으면 배터리 수준을 업데이트해야합니다. 여기

내가 뭘하는지 몇 가지 예제 코드입니다 :

DetailViewController.m

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    // Do any additional setup after loading the view. 
    NSLog(@"Selected tag UUID: %@", [selectedTag.tagUUID UUIDString]); 
    tagName.text = selectedTag.mtagName; 
    if(selectedTag.batteryLevel != nil){ 
     batteryLife.text = selectedTag.batteryLevel; 
    } 

    uuidLabel.text = [selectedTag.tagUUID UUIDString]; 

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setBatteryLevel:) name:@"SetBatteryLevel" object:nil]; 
} 
... 
-(void)setBatteryLevel:(NSNotification*)notif{ 
    NSMutableString* batLevel = [[NSMutableString alloc]initWithString:[NSString stringWithFormat:@"%@", selectedTag.batteryLevel]]; 
    [batLevel appendString:@" %"]; 
    selectedTag.batteryLevel = batLevel; 
    batteryLife.text = selectedTag.batteryLevel; 
} 

BluetoothLEManager.m :

... 
-(void) getBatteryLevel:(CBCharacteristic *)characteristic error:(NSError *)error fetchTag:(FetchTag *)fetchTag 
{ 
    NSLog(@"Getting battery Level..."); 
    NSData* data = characteristic.value; 
    const uint8_t* reportData = [data bytes]; 
    uint16_t batteryLevel = reportData[0]; 
    selectedTag.batteryLevel = [NSString stringWithFormat:@"%i", batteryLevel]; 
    NSLog(@"Battery Level is %@", [NSString stringWithFormat:@"%i", batteryLevel]); 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"SetBatteryLevel" object:nil]; 


} 
... 

는 다른 코드가 필요 알려줘 , 그러나 이것 모두의 기본입니다.

+1

블록/위임자 대신 NSNotification의 문제는 NSNotification이 전역이라는 것입니다. 누가 듣고 있는지, 그리고 수신자가 여전히 기억에 있는지 잘 모를 것입니다. 일단 NSNotification을 발송하면 그것이 받았는지 전혀 알 수 없습니다. 블록/델리게이트를 사용하면, 누가 당신에게 그것을 보내고 대리인에 대한'selector'를 호출하는지 정확히 알 수 있습니다. NSNotifications는 글로벌 일에 더 많이 사용되지만 대상을 원하는 경우 대리인/차단만큼 깨끗하지는 않습니다. – LyricalPanda

+0

코코아 (코코아 터치)의 가장 훌륭하고 강력한 기능 중 하나 인 핵심 가치 관찰 (KVO)에 대해 알아야 할 세 번째 방법이 있습니다. – Jef

답변

2

각 접근 방식에는 각각 다른 장단점이 있습니다.

대리인 및 프로토콜에는 개체와 해당 대리인, 일대일 관계 사이에 정의 된 인터페이스가 필요하며 개체에는 호출 할 대리인 개체에 대한 구체적인 지식이 필요합니다.

완료 블록이있는 메소드에는 객체와 메소드를 호출하는 객체간에 비슷한 일대일 관계가 있습니다. 그러나 블록은 정의 된 범위를 상속하므로 완료 블록에서 사용할 수있는 컨텍스트에 대한 유연성이 더 높아집니다. 블록을 사용하면 호출자가 호출이 수행되는 곳과 동일한 위치에서 완료 코드를 정의 할 수 있으므로 더 많은 자체 문서화를 코딩 할 수 있습니다.

두 경우 모두 대리인에게 알리거나 완료 블록을 호출하는 개체는 대화 대상자 또는 실행중인 코드를 알아야합니다.

델리게이트 콜은 차를 마쳤다는 것을 알려주는 자동 쇼핑몰과 같습니다. 서비스 관리자는 전화 번호를 알고 전화를 원한다는 것을 알고 있어야합니다.

블록은 요리사에게주는 요리법과 같습니다. 주방장에게 다른 요리법을 알려 주면 다른 작업을 수행합니다.

알림은 밀접하게 결합되지 않습니다. 그것은 군중 같은 공공 광장에서 공지 사항을 외치는 마을 뜰과 같다. 누가 듣고 있는지, 얼마나 많은 사람들이 듣고 있는지 알 필요가 없습니다.

마찬가지로, 알림을 보낼 때 누구인지, 누가 청취하고 있는지, 청취자가 몇 명인지는 알 수 없습니다. 당신은 알 필요가 없습니다. 방송중인 메시지에 대해 10 개의 개체가 신경 쓰면 모두들 청취 할 수 있으며 모두 알려줍니다. 메시지 발신자는 누가 듣고 있는지 알 필요가 없습니다.

간혹 가벼운 커플 링을 원할 때가 있습니다. 때로는 느슨한 커플 링을 원할 때도 있습니다. 그것은 당신이 해결하려고하는 문제에 달려 있습니다.

+0

답변 해 주셔서 감사합니다. 그것은 저를 위해 원근법에있는 것을 실제로두고 저를 다름을 이해할 것을 도왔습니다. 다시 한 번 감사드립니다! – BlackHatSamurai

관련 문제