首页编程stringwithformat(stringWithFormat 和 initWithFormat 有何不同)

stringwithformat(stringWithFormat 和 initWithFormat 有何不同)

编程之家2023-11-02100次浏览

这篇文章给大家聊聊关于stringwithformat,以及stringWithFormat 和 initWithFormat 有何不同对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。

stringwithformat(stringWithFormat 和 initWithFormat 有何不同)

如何使用Multipeer Connectivity

Multipeer connectivity是一个使附近设备通过Wi-Fi网络、P2P Wi-Fi以及蓝牙个人局域网进行通信的框架。互相链接的节点可以安全地传递信息、流或是其他文件资源,而不用通过网络服务。

Advertising& Discovering

通信的第一步是让大家互相知道彼此,我们通过广播(Advertising)和发现(discovering)服务来实现。

stringwithformat(stringWithFormat 和 initWithFormat 有何不同)

广播作为服务器搜索附近的节点,而节点同时也去搜索附近的广播。在许多情况下,客户端同时广播并发现同一个服务,这将导致一些混乱,尤其是在client-server模式中。

所以,每一个服务都应有一个类型(标示符),它是由ASCII字母、数字和“-”组成的短文本串,最多15个字符。通常,一个服务的名字应该由应用程序的名字开始,后边跟“-”和一个独特的描述符号。(作者认为这和 com.apple.*标示符很像),就像下边:

static NSString* const XXServiceType=@"xx-service";

一个节点有一个唯一标示MCPeerID对象,使用展示名称进行初始化,它可能是用户指定的昵称,或是单纯的设备名称。

MCPeerID*localPeerID= [[MCPeerID alloc] initWithDisplayName:[[UIDevice currentDevice] name]];

stringwithformat(stringWithFormat 和 initWithFormat 有何不同)

节点使用NSNetService或者Bonjour C API进行手动广播和发现,但这是一个特别深入的问题,关于手动节点管理可具体参见MCSession文档。

Advertising

服务的广播通过MCNearbyServiceAdvertiser来操作,初始化时带着本地节点、服务类型以及任何可与发现该服务的节点进行通信的可选信息。

发现信息使用Bonjour TXT records encoded(according to RFC 6763)发送。

MCNearbyServiceAdvertiser*advertiser= [[MCNearbyServiceAdvertiser alloc] initWithPeer:localPeerID discoveryInfo:nil serviceType:XXServiceType]; advertiser.delegate= self; [advertiser startAdvertisingPeer];

相关事件由advertiser的代理来处理,需遵从MCNearbyServiceAdvertiserDelegate协议。

在下例中,考虑到用户可以选择是否接受或拒绝传入连接请求,并有权以拒绝或屏蔽任何来自该节点的后续请求选项。

#pragma mark- MCNearbyServiceAdvertiserDelegate-(void)advertiser:(MCNearbyServiceAdvertiser*)advertiser didReceiveInvitationFromPeer:(MCPeerID*)peerID withContext:(NSData*)context invitationHandler:(void(^)(BOOL accept, MCSession*session))invitationHandler{ if([self.mutableBlockedPeers containsObject:peerID]){ invitationHandler(NO, nil); return;} [[UIActionSheet actionSheetWithTitle:[NSString stringWithFormat:NSLocalizedString(@"Received Invitation from%@",@"Received Invitation from{Peer}"), peerID.displayName] cancelButtonTitle:NSLocalizedString(@"Reject", nil) destructiveButtonTitle:NSLocalizedString(@"Block", nil) otherButtonTitles:@[NSLocalizedString(@"Accept", nil)] block:^(UIActionSheet*actionSheet, NSInteger buttonIndex){ BOOL acceptedInvitation=(buttonIndex== [actionSheet firstOtherButtonIndex]); if(buttonIndex== [actionSheet destructiveButtonIndex]){ [self.mutableBlockedPeers addObject:peerID];} MCSession*session= [[MCSession alloc] initWithPeer:localPeerID securityIdentity:nil encryptionPreference:MCEncryptionNone]; session.delegate= self; invitationHandler(acceptedInvitation,(acceptedInvitation? session: nil));}] showInView:self.view];}

为了简单起见,本例中使用了一个带有block的actionsheet来作为操作框,它可以直接给invitationHandler传递信息,用以避免创建和管理delegate造成的过于凌乱的业务逻辑,以避免创建和管理自定义delegate object造成的过于凌乱的业务逻辑。这种方法可以用category来实现,或者改编任何一个CocoaPods里有效的实现。

Creating a Session

在上面的例子中,我们创建了session,并在接受邀请连接时传递到节点。一个MCSession对象跟本地节点标识符、securityIdentity以及encryptionPreference参数一起进行初始化。

MCSession*session= [[MCSession alloc] initWithPeer:localPeerID securityIdentity:nil encryptionPreference:MCEncryptionNone]; session.delegate= self;

securityIdentity是一个可选参数。通过X.509证书,它允许节点安全识别并连接其他节点。当设置了该参数时,第一个对象应该是识别客户端的SecIdentityRef,接着是一个或更多个用以核实本地节点身份的SecCertificateRef objects。

encryptionPreference参数指定是否加密节点之间的通信。MCEncryptionPreference枚举提供的三种值是:

MCEncryptionOptional:会话更喜欢使用加密,但会接受未加密的连接。

MCEncryptionRequired:会话需要加密。

MCEncryptionNone:会话不应该加密。

启用加密会显著降低传输速率,所以除非你的应用程序很特别,需要对用户敏感信息的处理,否则建议使用MCEncryptionNone。

MCSessionDelegate协议将会在发送和接受信息的部分被覆盖.

Discovering

客户端使用MCNearbyServiceBrowser来发现广播,它需要local peer标识符,以及非常类似MCNearbyServiceAdvertiser的服务类型来初始化:

MCNearbyServiceBrowser*browser= [[MCNearbyServiceBrowser alloc] initWithPeer:localPeerID serviceType:XXServiceType]; browser.delegate= self;

可能会有很多节点广播一个特定的服务,所以为了方便用户(或开发者),MCBrowserViewController将提供一个内置的、标准的方式来呈现链接到广播节点:

MCBrowserViewController*browserViewController= [[MCBrowserViewController alloc] initWithBrowser:browser session:session]; browserViewController.delegate= self; [self presentViewController:browserViewController animated:YES completion: ^{ [browser startBrowsingForPeers];}];

当browser完成节点连接后,它将使用它的delegate调用browserViewControllerDidFinish:,以通知展示视图控制器--它应该更新UI以适应新连接的客户端。

Sending& Receiving Information

一旦节点彼此相连,它们将能互传信息。Multipeer Connectivity框架区分三种不同形式的数据传输:

Messages是定义明确的信息,比如端文本或者小序列化对象。

Streams流是可连续传输数据(如音频,视频或实时传感器事件)的信息公开渠道。

Resources是图片、电影以及文档的文件。

Messages

Messages使用-sendData:toPeers:withMode:error::方法发送。

NSString*message=@"Hello, World!"; NSData*data= [message dataUsingEncoding:NSUTF8StringEncoding]; NSError*error= nil; if(![self.session sendData:data toPeers:peers withMode:MCSessionSendDataReliable error:&error]){ NSLog(@"[Error]%@", error);}

通过MCSessionDelegate方法-sessionDidReceiveData:fromPeer:收取信息。以下是如何解码先前示例代码中发送的消息:

#pragma mark- MCSessionDelegate-(void)session:(MCSession*)session didReceiveData:(NSData*)data fromPeer:(MCPeerID*)peerID{ NSString*message= [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@", message);}

另一种方法是发送NSKeyedArchiver编码的对象:

id<NSSecureCoding> object=//...; NSData*data= [NSKeyedArchiver archivedDataWithRootObject:object]; NSError*error= nil; if(![self.session sendData:data toPeers:peers withMode:MCSessionSendDataReliable error:&error]){ NSLog(@"[Error]%@", error);}#pragma mark- MCSessionDelegate-(void)session:(MCSession*)session didReceiveData:(NSData*)data fromPeer:(MCPeerID*)peerID{ NSKeyedUnarchiver*unarchiver= [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; unarchiver.requiresSecureCoding= YES; id object= [unarchiver decodeObject]; [unarchiver finishDecoding]; NSLog(@"%@", object);}

为了防范对象替换攻击,设置requiresSecureCoding为YES是很重要的,这样如果根对象类没有遵从<NSSecureCoding>,就会抛出一个异常。欲了解更多信息,请参阅[NSHipster article on NSSecureCoding]。

Streams

Streams使用-startStreamWithName:toPeer:创建:

NSOutputStream*outputStream= [session startStreamWithName:name toPeer:peer]; stream.delegate= self; [stream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; [stream open];//...

Streams通过MCSessionDelegate的方法session:didReceiveStream:withName:fromPeer:来接收:

#pragma mark- MCSessionDelegate-(void)session:(MCSession*)session didReceiveStream:(NSInputStream*)stream withName:(NSString*)streamName fromPeer:(MCPeerID*)peerID{ stream.delegate= self; [stream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; [stream open];}

输入和输出的streams必须安排好并打开,然后才能使用它们。一旦这样做,streams就可以被读出和写入。

Resources

Resources发送使用-sendResourceAtURL:withName:toPeer:withCompletionHandler::

NSURL*fileURL= [NSURL fileURLWithPath:@"path/to/resource"]; NSProgress*progress= [self.session sendResourceAtURL:fileURL withName:[fileURL lastPathComponent] toPeer:peer withCompletionHandler:^(NSError*error){ NSLog(@"[Error]%@", error);}];

返回的NSProgress对象可以是通过KVO(Key-Value Observed)来监视文件传输的进度,并且它提供取消传输的方法:-cancel。

接收资源实现MCSessionDelegate两种方法:-session:didStartReceivingResourceWithName:fromPeer:withProgress:和-session:didFinishReceivingResourceWithName:fromPeer:atURL:withError:

#pragma mark- MCSessionDelegate-(void)session:(MCSession*)session didStartReceivingResourceWithName:(NSString*)resourceName fromPeer:(MCPeerID*)peerID withProgress:(NSProgress*)progress{//...}-(void)session:(MCSession*)session didFinishReceivingResourceWithName:(NSString*)resourceName fromPeer:(MCPeerID*)peerID atURL:(NSURL*)localURL withError:(NSError*)error{ NSURL*destinationURL= [NSURL fileURLWithPath:@"/path/to/destination"]; NSError*error= nil; if(![[NSFileManager defaultManager] moveItemAtURL:localURL toURL:destinationURL error:&error]){ NSLog(@"[Error]%@", error);}}

再次说明,在传输期间NSProgress parameter in-session:didStartReceivingResourceWithName:fromPeer:withProgress:允许接收节点来监控文件传输进度。在-session:didFinishReceivingResourceWithName:fromPeer:atURL:withError:中,delegate的责任是从临时localURL移动文件至永久位置。

Multipeer是突破性的API,其价值才刚刚开始被理解。虽然完整的支持功能比如AirDrop目前仅限于最新的设备,你应该会看到它将成为让所有人盼望的功能。

iOS wkwebview怎么写localStorage

iOS中WKWebView,存在首次加载h5页面,h5页面中的js就拿不到localstorage了。

WKWebView localStorage缓存很严重

HTML5在客户端存储数据的方式:cookie, localStorage, sessionStorage

cookie:只能存储少量的数据,常用来存储账号密码等

localStorage:没有时间限制的数据存储

sessionStorage:针对一个 session的数据存储,当网页关闭时,数据也会被删除。

1.WKWebView设置localStorage

NSString* userContent= [NSString stringWithFormat:@"{"token":"%@","userId":%@}",@"a1cd4a59-974f-44ab-b264-46400f26c849",@"89"];

//设置localStorage

NSString*jsString= [NSString stringWithFormat:@"localStorage.setItem('userContent','%@')", userContent];

//移除localStorage

// NSString*jsString=@"localStorage.removeItem('userContent')";

//获取localStorage

// NSString*jsString=@"localStorage.getItem('userContent')";

[self.webView evaluateJavaScript:jsString completionHandler:nil];

NSString* userContent=@"{"name":"Tom","age": 10}"];

//设置localStorage

NSString*jsString= [NSString stringWithFormat:@"localStorage.setItem('userContent','%@')", userContent];

//移除localStorage

// NSString*jsString=@"localStorage.removeItem('userContent')";

//获取localStorage

// NSString*jsString=@"localStorage.getItem('userContent')";

[self.webView stringByEvaluatingJavaScriptFromString:jsString];

//清理掉所有的localStorage数据

//NSString*clearString=@"localStorage.clear()";

iOS wkwebview localstorage数据处理

WKWebView在内存占用上优化的很多。但是在实践中发现bug:localstorage信息不一致。

A页面和B页面都存在一个WKWebView。在B页面使用localstorage保存信息。回到A页面取不到最新的数据。

原因:

https://developer.apple.com/reference/webkit/wkwebviewconfiguration中有个属性 processPool,描述是:The process pool from which to obtain the view’s Web Content process.

解决方法:

把config中的processPool变为单例共享

}

设置webview的配置 config.processPool= [NYWKWebView singleWkProcessPool];

在查询资料的过程中,发现了很多Local Storage的缺陷,有一篇关于Local Storage的论文可以参考。有以下几点:

webview和 iframe有什么区别?

webview是网页的原生载体,用于在原生环境中加载一个页面,iframe是网页的html载体,用于在网页中加载一个页面

ios appendstring怎么用

大部分的时候NSString的属性都是copy,那copy与strong的情况下到底有什么区别呢?

比如:

@property(retain,nonatomic) NSString*rStr;

@property(copy, nonatomic) NSString*cStr;

-(void)test:

{

NSMutableString*mStr= [NSMutableStringstringWithFormat:@"abc"];

self.rStr= mStr;

self.cStr= mStr;

NSLog(@"mStr:%p,%p", mStr,&mStr);

NSLog(@"retainStr:%p,%p", _rStr,&_rStr);

NSLog(@"copyStr:%p,%p", _cStr,&_cStr);

假如,mStr对象的地址为0x11,也就是0x11是@“abc”的首地址,mStr变量自身在内存中的地址为0x123;

当把mStr赋值给retain的rStr时,rStr对象的地址为0x11,rStr变量自身在内存中的地址为0x124;rStr与mStr指向同样的地址,他们指向的是同一个对象@“abc”,这个对象的地址为0x11,所以他们的值是一样的。

当把mStr赋值给copy的cStr时,cStr对象的地址为0x22,cStr变量自身在内存中的地址0x125;cStr与mStr指向的地址是不一样的,他们指向的是不同的对象,所以copy是深复制,一个新的对象,这个对象的地址为0x22,值为@“abc”。

stringWithFormat 和 initWithFormat 有何不同

1、initWithFormat是实例办法

只能经由过程 NSString* str= [[NSString alloc] initWithFormat:@"%@",@"Hello World"]调用,然则必须手动release来开释内存资料

2、stringWithFormat是类办法

可以直接用 NSString* str= [NSString stringWithFormat:@"%@",@"Hello World"]调用,内存经管上是autorelease的,不消手动显式release

+ stringWithFormat:

类方法,返回一个autorelease的NSString实例,不用手动Release,在自动释放池中会自动释放。

initWithFormat:

实例方法,返回一个自己Alloc申请内存的NSString实例,根据OC内存管理黄金法则,管杀管埋,它则需要自己手动Release。

因为这两个方法只是在没有使用ARC的时候有所不同,一个需要手动Release一个则是自动进入autoreleasepool,所以在使用ARC的时候他们俩几乎没有什么区别。

OK,关于stringwithformat和stringWithFormat 和 initWithFormat 有何不同的内容到此结束了,希望对大家有所帮助。

站长新闻?站长工具平台武汉做网站的公司,武汉做网站的公司有哪些