// PackagesViewController.h
#import <UIKit/UIKit.h>
@interface PackagesViewController : UITableViewController {
NSMutableArray *packages;
}
@end
// PackagesViewController.m
#import "PackagesViewController.h"
@implementation PackagesViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self findGroup:packages];
}
- (void)findGroup:(NSMutableArray *)array {
}
@end
예를 들어 위와같이 private 메서드목적으로 findGroup메서드를 정의할 수 있고 이 메서드는 .h파일에는 명시하지 않았고 위에서 [self findGroup]와 같은 형태로 호출을 합니다.
하지만 여기에 문제가 있는데 컴파일러가 private 메서드의 여부를 알지 못한다는 것입니다. 컴파일러는 .h파일에 정의된 선언만 확인하기 때문입니다. 때문에 @implementation부분에서 private 메서드를 호출할 경우 해당 메서드는 .h파일에 정의가 안되어있으므로 아래 화면처런 findGroup가 없다는 경고메시지를 보여줍니다. 물론 실제로는 동작하기 때문에 실행을 하면 findGroup가 정상적으로 호출이 됩니다.(컴파일러가 메서드의 존재여부에 대한 정보를 가질 수 없었을 뿐입니다.) 하지만 개발자로써 의도한 정상적인 코드에 경고메시지가 나타나는 것은 상당히 신경쓰이는 일입니다.
이 문제를 카테고리 기능을 사용해서 해결할 수 있습니다.
// PackagesViewController.m
#import "PackagesViewController.h"
@interface PackagesViewController(Private)
- (void)findGroup:(NSMutableArray *)array;
@end
@implementation PackagesViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self findGroup:packages];
}
@end
@implementation PackagesViewController (Private)
- (void)findGroup:(NSMutableArray *)array {
}
@end
위와 같이 카테고리 기능을 이용해서 Private라는 이름의(다른 이름도 됩니다.) 카테고리를 만들고 이 카테고리를 구현한 @implementation을 정의해서 이곳에 메서드를 구현해 주면 됩니다. 이렇게 구현하면 컴파일러 경고 없이 private method를 사용할 수 있습니다. 구현부를 따로 나누고 싶지 않다면 이름이 없는 카테고리 기능을 사용해서 해결할 수 있습니다. 이 이름이 없는 카테고리 기능을 class continuation이라고 부른다고 합니다.
// PackagesViewController.m
#import "PackagesViewController.h"
@interface PackagesViewController()
- (void)findGroup:(NSMutableArray *)array;
@end
@implementation PackagesViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self findGroup:packages];
}
- (void)findGroup:(NSMutableArray *)array {
}
@end
이렇게 작성해도 동일하게 동작하며 2가지 방법 모두 카테고리에 정의한 메서드를 구현하지 않으면 컴파일러 경고가 뜨기 때문에 실수도 방지할 수 있습니다.(컴파일 오류는 나지 않습니다.)
2가지 방법 중 작성이 좀 더 편리한 class continuation쪽이 낫지 않나 생각하고 있습니다. 저도 공부중이라 위에서 언급한 부분외의 차이점외에는 아직 잘 모르겠습니다. A Quick Objective-C 2.0 Tutorial: Part II에서는 카테고리를 사용했을때의 컴파일러 경고에 대해서 언급하고 그 대안으로 class continuation에 대해서 언급하고 있지만 이리 저리 테스트해봤는데(아직 초심자라 디테일한 테스트라하기는 어렵지만) 딱히 언급된 문제는 찾을 수 없었습니다.
m 파일 implementation 위에 아래처럼 쓰면 됩니다.
@interface ANObject ()
{
;
}
-(void)somePrivateMethod; // private 함수들..
@end
제가 요즘은 obj-c를 안보고 있어서 몰라서 그러는데 본문에서 2번째 방법과 같은 방법 아닌가요?