2

我试图在 Objective-C 类别与 Java 和 Ruby 中的功能之间进行比较。请看看这些结论是否准确——

即使您无权访问该类的源代码,Objective-C 类别也会向现有类添加新方法。Java 没有类似的东西,但在 Ruby 中,您可以“打开”任何类,包括像 String 这样的核心语言类。

class String 
  def my_new_method
  "new test method"
 end
end

"some string".my_new_method
=> "new test method"

同样在 Objective-C 中 - 您可以使用类别“重新打开” NSString 类。

#import "NSString+ForTest.h"

@implementation NSString (ForTest)

-(NSString*) myNewMethod {
  return @"new test method";
}

@end

但是,我看到的一个区别是,在 Ruby 中,一旦在运行时中打开和修改了一个类,该类的所有后续使用都会受到影响,换句话说,这是一个系统范围的更改,而在 Objective-C 中只有代码导入此头文件(和任何子类)会受到影响。还有其他区别吗?

4

2 回答 2

3

但是,我看到的一个区别是,在 Ruby 中,一旦在运行时中打开和修改了一个类,该类的所有后续使用都会受到影响,换句话说,这是一个系统范围的更改,而在 Objective-C 中只有代码导入此头文件(和任何子类)受到影响

不——在 Objective-C 中,使用类扩展编译的程序(或库)中的所有类都会受到影响,即使您的代码从未导入相关的头文件,因此该功能与 Ruby 的功能非常相似。

于 2013-09-07T17:30:33.853 回答
2

另一个区别是,在 ruby​​ 中,您可以打开一个类并将实例变量添加到该类中:

irb(main):002:0> class String
irb(main):003:1> def a=(v)
irb(main):004:2> @v = v
irb(main):005:2> end
irb(main):006:1> def a
irb(main):007:2> @v
irb(main):008:2> end
irb(main):009:1> end
=> nil
irb(main):010:0> s = "string"
=> "string"
irb(main):011:0> s.a = "blah"
=> "blah"
irb(main):012:0> s.a
=> "blah"

在 Objective-C 类别中,您不能将实例变量添加到现有类。

但是,您可以使用运行时将一个对象与另一个对象相关联,人们经常使用它来添加从界面看起来像的属性/ivars。

如何在对象内使用 objc_setAssociatedObject/objc_getAssociatedObject?

于 2013-09-07T17:48:26.403 回答