请考虑以下步骤:
1)在Xcode中创建一个新的“单一视图应用程序”.
2)创建一个类NSObject Extension.h和.m文件:
// .h @interface NSObject (Extension) - (void)someMethod; @end // .m @implementation NSObject (Extension) - (void)someMethod { NSLog(@"someMethod was called"); } @end
3)确保NSObject Extension.m文件包含在主目标中.
4)将以下行添加到AppDelegate中:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [[NSString new] performSelector:@selector(someMethod)]; return YES; }
5)确保#import“NSObject Extension.h行在应用程序中不存在!
6)运行应用程序.
输出是
2013-08-27 04:12:53.642 Experimental[32263:c07] someMethod was called
问题
>我想知道在应用程序中是否有任何这个类别的任何#import,NSString甚至还有NSObject Extension可用吗?这个行为让我对每个我声明的Objective-C类感到非常糟糕,因为我希望我声明的类别只能在它们被声明的范围内可用.例如,我希望NSObject只在一些类中扩展,而不是在整个应用程序中,因为它的全局空间变得“被污染”.
有没有办法避免这种行为?我确实希望我的类别只有在我明确导入它们时才能工作,而不是当我将它们链接到我用来运行的目标时.
解决方法
I wonder if there is no any #import of this category anywhere in the app,how is it even possible that NSString does still have NSObject+Extension available? This behavior makes me feeling very bad about every Objective-C category I declare because I want the categories I declare to be available only in the scopes they are declared within. For example,I want NSObject to be extended by Extension only in some class but not in the whole app because its globalspace becomes “polluted” otherwise.
Objective-C对象上没有命名空间.如果您声明一个类有一个方法(无论是通过类别还是在主@interface中),那么该类的每个实例都将具有该方法.
Objective-C处理“私有”方法的方法是通过选择不向别人告知有关方法(这是通过不导入声明这些方法的文件来实现的).这个,加上-Wundeclared-selector(如果你使用编译器不知道的选择器,那么警告)就像你要得到的一样好.
但是,无论如何将.m文件编译到最终的二进制文件中,即使没有其他人“知道”,该方法也会存在.
Are there way to avoid this behavior? I do want my categories to work only when I explicitly import them,not just when I have them linked to a target I use to run.
是的,使用-Wundeclared选择器,Xcode会警告你.