NSObject详解

NSObject Class Reference

Initializing a Class

1.+ (void)initialize
一个类的实例在使用前需要先初始化.

initialize 在一个类中只被调用一次。如果你想为一个类或类的Categories执行独立的初始化,你可以实现load方法。

2.+ (void)load
无论何时,只要一个类或者Categories只要被添加到Objective-C的运行时就会调用此方法;加载后实现这个方法来执行类的特殊行为。

Creating, Copying, and Deallocating Objects

1.+ (id)alloc
返回一个新的实例。
必须和init一起使用iClass* iclass = [[iClass alloc] init];
2.+ (id)allocWithZone:(NSZone *)zone
返回一个新的实例。
必须和init一起使用iClass* iclass = [[iClass allocWithZone:nil] init];

This method exists for historical reasons; memory zones are no longer used by Objective-C.

3.- (id)init
当一个新对象申请了内存空间,就会立刻调用init方法来初始化这个对象。
在NSObject类中定义的init方法没有初始化,只是返回了self指针。

TheClass *newObject = [[TheClass alloc] init]; alloc和init一起使用

4.- (id)copy
返回一个通过copyWithZone:创建的实例。

This is a convenience method for classes that adopt the NSCopying protocol. An exception is raised if there is no implementation forcopyWithZone:.

NSObject does not itself support the NSCopying protocol. Subclasses must support the protocol and implement thecopyWithZone: method. A subclass version of thecopyWithZone: method should send the message tosuper first, to incorporate its implementation, unless the subclass descends directly fromNSObject.

5.+ (id)copyWithZone:(NSZone *)zone
当你需要一个实现NSCopying协议的对象时,可以使用此方法。例如,把一个类对象作为NSDictionary的key值

You should not override this method.

6.- (id)mutableCopy
当zoon为nil的时候,通过NSMutableCopying  协议方法 mutableCopyWithZone:创建的对象。

对一个采用 NSMutableCopying协议的类来说这是一个方便的方法。如果没有实现mutableCopyWithZone:的话就会抛异常。

This is a convenience method for classes that adopt the NSMutableCopying protocol. An exception is raised if there is no implementation formutableCopyWithZone:.

7.+ (id)mutableCopyWithZone:(NSZone *)zone
雷同copyWithZone:(NSZone *)zone
8.+ (id)new

分配一个实例新的内存空间,调用init方法,最后返回一个初始化过的对象。

This method is a combination of alloc andinit. Likealloc, it initializes theisa instance variable of the new object so it points to the class data structure. It then invokes theinit method to complete the initialization process.

Identifying Classes

1.+ (Class)class
返回一个class”对象“
2.+ (Class)superclass
返回一个类的父类Class

3.+ (BOOL)isSubclassOfClass:(Class)aClass
判断一个类是否是另一个类的子类。

Testing Class Functionality

1.+ (BOOL)instancesRespondToSelector:(SEL)aSelector
判断一个实例变量是否能够调用一个类的方法
比如,
BOOL boolValue = [ NSArray instancesRespondToSelector: @selector(initWithArray:)];返回YES;

BOOL boolValue = [NSArrayinstancesRespondToSelector:@selector(arrayWithArray:)];返回NO

Testing Protocol Conformance

1.+ (BOOL)conformsToProtocol:(Protocol *)aProtocol
判断一个接收者是否能够遵从一个给定的protocol。一个接收者遵从一个协议,可以是直接接受这个协议,也可以继承一个已经接受这个协议的类。

Obtaining Information About Methods

1.- (IMP)methodForSelector:(SEL)aSelector

定位并且返回接收者实现该方法的地址,因此可以作为一个方法来调用。

传入参数aSelector必须是有效切非空的,可以用respondsToSelector: 这个方法提前判断。

@interface TestIMP : NSObject

- (void)saySomething;

@end

@implementation TestIMP

- (void)saySomething
{
    NSLog(@"invoke saySomething");
}

@end

// For Test
TestIMP *testIMP = [[TestIMP alloc] init];

SEL aSelector = @selector(saySomething);

IMP imp = [testIMP methodForSelector:aSelector];

imp(testIMP, aSelector);
2.+ (IMP)instanceMethodForSelector:(SEL)aSelector
- (IMP)methodForSelector:(SEL)aSelector
3.+ (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector
返回NSMethodSignature对象,这个对象包含被标示的实例方法的描述。
4.- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
+ (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector

Describing Objects

1.+ (NSString *)description
以字符串的形式返回对接收者类内容的描述。

Discardable Content Proxy Support

1.- (id)autoContentAccessingProxy
创建一个接收者对象的代理。

Sending Messages

1.- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay
延时调用在当前线程使用默认模式的方法
2.- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray *)modes
延时调用在当前线程使用特定模式的方法

anArgument

如果想把需要的数据传给Selector方法中,需要设置anArgument参数,对应Selector就应是带参数的方法

modes
如果这个参数为空或者数组中没有数据,那么就不会调用Selector方法。
[self performSelector:@selector(doSomething:)
               withObject:[NSArray arrayWithObjects:@"AObject", @"BObject", nil]
               afterDelay:1.0
                  inModes:[NSArray arrayWithObjects:NSDefaultRunLoopMode, nil]];

- (void)doSomething:(id)sender
{
    NSLog(@"invoke doSomething");

    NSLog(@"%@", sender);
}
3.- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
以默认的方式在主线程中调用一个方法
wait
如果设置为YES那么将阻塞当前线程,设置为NO将立刻调用Selector方法
如果当前线程也是主线程,那么设置为YES,Selector方法将会立即调用,arg信息也会立即传输。
这个方法是不可以被取消的,如果想调用取消方法可以使用 performSelector:withObject:afterDelay:或者 performSelector:withObject:afterDelay:inModes:方法
4.- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait,只是多了一个可以选择RunLoop模式的参数。
5.- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thread withObject:(id)arg waitUntilDone:(BOOL)wait
在指定的线程中执行指定的Selector方法。
其它内容与第3条相同。
6.- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thread withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array
是多了一个可以选择RunLoop模式的参数,其它与第5条相同。
7.- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg
在一个新的后台线程中调用Selector方法
8.+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget
取消执行先前用 performSelector:withObject:afterDelay:这个方法创建的实例方法。取消的只是当前RunLoop里执行的方法而不是所有RunLoop.

performSelector:onThread:withObject:waitUntilDone:performSelectorInBackground:withObject:执行的方法不能被取消。

9.+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(id)anArgument
同第8个方法,只是多了Selector方法和要传递的数据。 但是经测试发现这个方法不能取消performSelector:withObject:afterDelay:执行的方法。(有知道原因的朋友就留言,谢谢)
测试方法如下:
[self performSelector:@selector(doSomething:)
               withObject:@"performSelector"
               afterDelay:1.0];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(threadAction) object:nil];

Forwarding Messages

1.- (id)forwardingTargetForSelector:(SEL)aSelector
返回消息被第一个转发的对象。
2.- (void)forwardInvocation:(NSInvocation *)anInvocation
实例如下:
@interface Car : NSObject
{
    NSString *_name;
    
    NSArray  *_array;;
}

@end

#import "Car.h"

@implementation Car

- (id)init
{
	self = [super init];
	if (self) {
		_name = [[NSString alloc] initWithString:@"I AM A CAR~~"];
		_array = [[NSArray alloc] initWithObjects:@"1", @"2", nil];
	}
	return self;
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
	NSMethodSignature* signature = [super methodSignatureForSelector:aSelector];
	if (signature == nil)
    {
		signature = [_array methodSignatureForSelector:aSelector];
	}
	NSUInteger argCount = [signature numberOfArguments];
	for (NSInteger i=0 ; i<argCount ; i++)
    {
		NSLog(@"%s" , [signature getArgumentTypeAtIndex:i]);
	}
	NSLog(@"methodReturnType:%s, methodReturnLength:%d" , [signature methodReturnType] , [signature methodReturnLength]);
	NSLog(@"signature:%@" , signature);
	return signature;
}

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
	SEL seletor = [anInvocation selector];
	if ([_array respondsToSelector:seletor])
    {
		[anInvocation invokeWithTarget:_array];
	}
    else
    {
        [super forwardInvocation:anInvocation];
    }
    
}

- (id)forwardingTargetForSelector:(SEL)aSelector
{
    NSLog(@"forwardingTargetForSelector");
    
    if ([_array respondsToSelector:aSelector])
    {
        return _array;
    }
    return nil;
}

- (void)dealloc
{
	[_name	release];
    [_array release];
    
	[super dealloc];
}

@end

测试方法如下:

Car *car = [[Car alloc] init];
NSLog(@"length = %d", [car count]);
[car release];
car实例本来没有count方法,但是通过消息转发实现了count方法。
部分参考http://blog.csdn.net/freshforiphone/article/details/7381329

Dynamically Resolving Methods

1.+ (BOOL)resolveClassMethod:(SEL)name
动态的为一个类方法提供了一个SEL实现方法。返回YES表明这个方法已经找到并被添加到接收者,否则返回NO。
2.+ (BOOL)resolveInstanceMethod:(SEL)name
动态的为一个实例方法提供了一个SEL实现方法。返回YES表明这个方法已经找到并被添加到接收者,否则返回NO。
实例如下:

@interface Person : NSObject
{
    NSString *name;
    float weight;
}

@property (retain,readwrite) NSString* name;
@property (readonly)float weight;
@property float height;

-(Person*) initWithWeight: (int) weight;
-(void) print: (NSString*) str;
@end

void dynamicMethod(id self,SEL _cmd,float w)
{
    printf("dynamicMethod-%s\n",[NSStringFromSelector(_cmd) cStringUsingEncoding:NSUTF8StringEncoding]);
    printf("%f\n",w);
}

@implementation Person
@synthesize name;
@synthesize weight;

@dynamic height; // 注意这里
// 在实现类中使用了@dynamic指令



-(Person*) initWithWeight: (int) w
{
    self=[super init];
    if (self)
    {
        weight=w;
    }
    
    return self;
}

-(void) print: (NSString*) str
{
    NSLog(@"%@%@",str,name);
}

+ (BOOL) resolveInstanceMethod: (SEL) sel
{
    NSString *methodName=NSStringFromSelector(sel);
    BOOL result=NO;
    
    //看看是不是我们要动态实现的方法名称
    if ([methodName isEqualToString:@"setHeight:"])
    {
        class_addMethod([self class], sel, (IMP) dynamicMethod,"v@:f");
        result=YES;
    }
    
    return result;
}

+ (BOOL)resolveClassMethod:(SEL)sel
{
    NSString *methodName=NSStringFromSelector(sel);
    BOOL result=NO;
    
    //看看是不是我们要动态实现的方法名称
    if ([methodName isEqualToString:@"setHeight:"])
    {
        class_addMethod([self class], sel, (IMP) dynamicMethod,"v@:f");
        result=YES;
    }
    
    return result;
}

-(void) dealloc
{
    [self setName:nil];
    [super dealloc];
}

@end

测试方法如下:

Person *person = [[Person alloc] init];
[person setHeight:100.0];
具体参考http://blog.csdn.net/namehzf/article/details/6904500     http://blog.csdn.net/ios_developer/article/details/9283199

Error Handling

1.- (void)doesNotRecognizeSelector:(SEL)aSelector
处理不被接收者识别的信息。

Archiving

1.- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder


2.- (Class)classForCoder


3.- (Class)classForKeyedArchiver


4.+ (NSArray *)classFallbacksForKeyedArchiver


5.+ (Class)classForKeyedUnarchiver

6.- (id)replacementObjectForCoder:(NSCoder *)aCoder

7.- (id)replacementObjectForCoder:(NSCoder *)aCoder

8.+ (void)setVersion:(NSInteger)aVersion

9.+ (NSInteger)version
获得指定给某一个类的版本号码。
如果没有设置版本号码,默认是0。

Don’t simply send version to the return value of class—a subclass version number may be returned instead.

Deprecated Methods

1.- (void)finalize

NSObject Protocol

Identifying Classes

1.- (Class)class
返回实例变量的Class对象,与 + (Class)class 相同。
2.- (Class)superclass
返回父Class,与 +(Class)superclass相同。

Identifying and Comparing Objects

1.- (BOOL)isEqual:(id)anObject
判断两个对象是否相等。
2.- (NSUInteger)hash
返回一个整数,可以在哈希表结构中当作一个地址。如果两个变量isEqual:相等,那么他们的hash值一定相同。
3.- (id)self
返回自己。

Testing Object Inheritance, Behavior, and Conformance

1.- (BOOL)isKindOfClass:(Class)aClass
判断一个变量是否是一个给定类的变量或者任何一个继承该类的类变量。
可以这样来使用:
ShakeViewController *shake = [[ShakeViewController alloc] init];
    
BOOL boolValue = [shake isKindOfClass:[NSObject class]];

// DO NOT DO THIS!
if ([myArray isKindOfClass:[NSMutableArray class]])
{
    // Modify the object
}
2.- (BOOL)isMemberOfClass:(Class)aClass
判断某一个实例是否是这个类的实例变量。
BOOL boolValue = [shake isMemberOfClass:[NSObject class]];
boolValue=NO,不支持继承类的判断
3.- (BOOL)respondsToSelector:(SEL)aSelector
ShakeViewController *shake = [[ShakeViewController alloc] init];
BOOL boolValue = [shake respondsToSelector:@selector(parentViewController)];
返回YES。
BOOL boolValue = [[shake superclass] respondsToSelector:@selector(parentViewController)];
返回NO。
BOOL boolValue = [ShakeViewController instancesRespondToSelector:@selector(parentViewController)];
返回YES。
BOOL boolValue = [[shake superclass] instancesRespondToSelector:@selector(parentViewController)];
返回YES。
4.- (BOOL)conformsToProtocol:(Protocol *)aProtocol
同+ (BOOL)conformsToProtocol:(Protocol *) aProtocol

Describing Objects

1.- (NSString *)description
同 + ( NSString *)description
2.- (NSString *)debugDescription
同+ ( NSString *)debugDescription

Sending Messages

1.- (id)performSelector:(SEL)aSelector
2.- (id)performSelector:(SEL)aSelector withObject:(id)anObject
3.- (id)performSelector:(SEL)aSelector withObject:(id)anObject withObject:(id)anotherObject
带两个参数的。

Identifying Proxies

1.- (BOOL)isProxy
判断一个实例不继承自NSObject,如果返回NO就是继承自NSObject,反之返回YES

Obsolete Methods

1.- (id)retain
增加接收者的引用计数。
2.- (oneway void)release
减少接收者的引用计数。
3.- (id)autorelease

Decrements the receiver’s retain count at the end of the current autorelease pool block. (required)

4.- (NSUInteger)retainCount
5.- (NSZone *)zone

Zones are deprecated and ignored by most classes that have it as a parameter. (required)





























  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
struct VideoPicker: UIViewControllerRepresentable { @Environment(.presentationMode) private var presentationMode let sourceType: UIImagePickerController.SourceType // let onImagePicked: (UIImage) -> Void let onURLPicked: (URL) -> Void final class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate { @Binding private var presentationMode: PresentationMode private let sourceType: UIImagePickerController.SourceType private let onURLPicked: (URL) -> Void init(presentationMode: Binding<PresentationMode>, sourceType: UIImagePickerController.SourceType, onURLPicked: @escaping (URL) -> Void) { presentationMode = presentationMode self.sourceType = sourceType self.onURLPicked = onURLPicked } func imagePickerController( picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { // let uiImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage // onImagePicked(uiImage) if let url = info[.mediaURL] as? URL{ onURLPicked(url) } presentationMode.dismiss() } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { presentationMode.dismiss() } } func makeCoordinator() -> Coordinator { return Coordinator(presentationMode: presentationMode, sourceType: sourceType, onURLPicked: onURLPicked) } func makeUIViewController(context: UIViewControllerRepresentableContext<VideoPicker>) -> UIImagePickerController { let picker = UIImagePickerController() picker.sourceType = sourceType picker.delegate = context.coordinator picker.mediaTypes = ["public.movie"] return picker } func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<VideoPicker>) { } }这段代码获取的url中绝对路径不准确
最新发布
05-24

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值