NSPort 這里就分為: 內(nèi)核端口、消息端口、套接字端口
// NSPort 用于線程和進(jìn)程之間的交互灸撰。
/*
為了讓mach向后兼容厘贼, +allocWithZone:發(fā)送到NSPort類時候返回NSMachPort類的實例睦袖。 否則习蓬, 它將會返回一個具體子類,該子類可用于本地機器上的線程或進(jìn)程之間的消息傳遞降盹。
*/
// NSPort 無效的通知
FOUNDATION_EXPORT NSNotificationName const NSPortDidBecomeInvalidNotification;
#pragra mark -- 有關(guān)NSPort里面的接口詳解
# NSPort 在iOS中更加像是一個基類
@interface NSPort : NSObject <NSCopying, NSCoding>
+ (NSPort *)port; // 默認(rèn)方法
// 使其無效 与柑、 是否有效
- (void)invalidate;
@property (readonly, getter=isValid) BOOL valid;
// 設(shè)置有關(guān)的代理
- (void)setDelegate:(nullable id <NSPortDelegate>)anObject;
- (nullable id <NSPortDelegate>)delegate;
// (1) 就是給端口添加監(jiān)聽
// (2)子類需要實現(xiàn)這個方法
// (3) 不應(yīng)該直接調(diào)用
// 這兩個方法應(yīng)該通過子類實現(xiàn),添加到runloop設(shè)置端口監(jiān)聽
// 從runloop中刪除停止端口監(jiān)聽。
// 這兩個不方法 不應(yīng)該直接調(diào)用价捧。
- (void)scheduleInRunLoop:(NSRunLoop *)runLoop forMode:(NSRunLoopMode)mode;
- (void)removeFromRunLoop:(NSRunLoop *)runLoop forMode:(NSRunLoopMode)mode;
// 傳輸API丑念, 子類必須實現(xiàn)這些方法
@property (readonly) NSUInteger reservedSpaceLength; // 保留空間長度,默認(rèn)是0
- (BOOL)sendBeforeDate:(NSDate *)limitDate components:(nullable NSMutableArray *)components from:(nullable NSPort *) receivePort reserved:(NSUInteger)headerSpaceReserved;
- (BOOL)sendBeforeDate:(NSDate *)limitDate msgid:(NSUInteger)msgID components:(nullable NSMutableArray *)components from:(nullable NSPort *)receivePort reserved:(NSUInteger)headerSpaceReserved;
// component 由于NSData子類的一系列實例和NSPort的子類實例組成的结蟋。
//因為NSPort的一個子類不一定知道如何傳輸NSPort子類實例(或者及其知道另一個子類也可以這樣做)脯倚,因為,components中的所有NSPort實例和“receivePort”參數(shù)必須與接收次消息的NSPort的子類相同嵌屎。如果在同一個程序中使用多個傳輸API推正, 需要注意。 【也就是發(fā)送的NSPort和接收的NSPort的對象類是一樣的【子類一樣】】
// OSX 和 OS_MACCATALYST 才有的接口宝惰,推薦使用NSXPCConnection
//
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
- (void)addConnection:(NSConnection *)conn toRunLoop:(NSRunLoop *)runLoop forMode:(NSRunLoopMode)mode NS_SWIFT_UNAVAILABLE("Use NSXPCConnection instead") API_DEPRECATED("Use NSXPCConnection instead", macosx(10.0, 10.13), ios(2.0,11.0), watchos(2.0,4.0), tvos(9.0,11.0));
- (void)removeConnection:(NSConnection *)conn fromRunLoop:(NSRunLoop *)runLoop forMode:(NSRunLoopMode)mode NS_SWIFT_UNAVAILABLE("Use NSXPCConnection instead") API_DEPRECATED("Use NSXPCConnection instead", macosx(10.0, 10.13), ios(2.0,11.0), watchos(2.0,4.0), tvos(9.0,11.0));
// 默認(rèn)實現(xiàn)這兩個方法去簡單添加接收端口在指定的mode上運行runloop植榕。 子類不需要重寫這些方法,除非需要額外的工作尼夺∽鸩校【也就是重寫要調(diào)用super 】
// MACCATALYST 參考連接 , 只要是見ipad app轉(zhuǎn)化為mac app
//https://blog.csdn.net/CrazyApp/article/details/109224506
//https://www.sohu.com/a/445339514_208051
#endif
@end
// NSPort的代理方法
@protocol NSPortDelegate <NSObject>
@optional
- (void)handlePortMessage:(NSPortMessage *)message;
// 子類必須發(fā)送這個代理方法淤堵,除非子類又更多具體的東西要先發(fā)送夜郁。
這是子類應(yīng)該發(fā)送給它們的委托的委托方法,除非子類有更具體的東西要先發(fā)送
@end
NSMachPort 內(nèi)核端口
#if TARGET_OS_OSX || TARGET_OS_IPHONE
NS_AUTOMATED_REFCOUNT_WEAK_UNAVAILABLE
@interface NSMachPort : NSPort {
@private
id _delegate;
NSUInteger _flags;
uint32_t _machPort;
NSUInteger _reserved;
}
// 初始化方法
+ (NSPort *)portWithMachPort:(uint32_t)machPort;
- (instancetype)initWithMachPort:(uint32_t)machPort NS_DESIGNATED_INITIALIZER;
- (void)setDelegate:(nullable id <NSMachPortDelegate>)anObject;
- (nullable id <NSMachPortDelegate>)delegate;
// 接收和發(fā)送到數(shù)據(jù)之后是否立即銷毀
typedef NS_OPTIONS(NSUInteger, NSMachPortOptions) {
NSMachPortDeallocateNone = 0,
NSMachPortDeallocateSendRight = (1UL << 0),
NSMachPortDeallocateReceiveRight = (1UL << 1)
} API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
+ (NSPort *)portWithMachPort:(uint32_t)machPort options:(NSMachPortOptions)f API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
- (instancetype)initWithMachPort:(uint32_t)machPort options:(NSMachPortOptions)f API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) NS_DESIGNATED_INITIALIZER;
@property (readonly) uint32_t machPort; // 端口數(shù)字
- (void)scheduleInRunLoop:(NSRunLoop *)runLoop forMode:(NSRunLoopMode)mode;
- (void)removeFromRunLoop:(NSRunLoop *)runLoop forMode:(NSRunLoopMode)mode;
@end
@protocol NSMachPortDelegate <NSPortDelegate>
@optional
//代理調(diào)用這個方法粘勒,否則調(diào)用原始的handlePortMessage 代理方法
- (void)handleMachMessage:(void *)msg;
@end
#endif
NSMessagePort 消息
// NSPortMessage 和 NSMessagePort 應(yīng)該是同一個東西
// 用于本地信息發(fā)送在所有的平臺上
NS_AUTOMATED_REFCOUNT_WEAK_UNAVAILABLE
@interface NSMessagePort : NSPort {
@private
void *_port;
id _delegate;
}
@end
// 用于遠(yuǎn)程信息發(fā)送在所有的平臺上
NSSocketPort 套接字
@interface NSSocketPort : NSPort {
@private
void *_receiver; // 接收器
id _connectors; // 連接器
void *_loops; // loop循環(huán)
void *_data; // 數(shù)據(jù)
id _signature; // 簽名
id _delegate; // 代理
id _lock; // 鎖
NSUInteger _maxSize;// 最大數(shù)目
NSUInteger _useCount; // 使用數(shù)目
NSUInteger _reserved; // 保留字段
}
- (instancetype)init;
- (nullable instancetype)initWithTCPPort:(unsigned short)port; // 通過端口初始化
- (nullable instancetype)initWithProtocolFamily:(int)family socketType:(int)type protocol:(int)protocol address:(NSData *)address NS_DESIGNATED_INITIALIZER;
// 通過協(xié)議族、地址進(jìn)行初始化
- (nullable instancetype)initWithProtocolFamily:(int)family socketType:(int)type protocol:(int)protocol socket:(NSSocketNativeHandle)sock NS_DESIGNATED_INITIALIZER;
// 協(xié)議socket初始化
- (nullable instancetype)initRemoteWithTCPPort:(unsigned short)port host:(nullable NSString *)hostName;
// 端口和主機名字
- (instancetype)initRemoteWithProtocolFamily:(int)family socketType:(int)type protocol:(int)protocol address:(NSData *)address NS_DESIGNATED_INITIALIZER;
// 協(xié)議和地址
@property (readonly) int protocolFamily; // 協(xié)議族
@property (readonly) int socketType; // 套接字類型
@property (readonly) int protocol; // 協(xié)議
@property (readonly, copy) NSData *address;// 地址數(shù)據(jù)
@property (readonly) NSSocketNativeHandle socket; //套接字 【句柄】
@end
可以看到這個是返回NSMatchPort屎即,并有帶有端口號
看一下如何進(jìn)行使用庙睡。
NSPort概念了解
NSPort 使用例子: 兩個線程通信
線程通信
線程通信方式
1)GCD的方式
2)NSObject中的perform
3)NSPort