{"action":"closed","issue":{"url":"https://api.github.com/repos/icepy/we-writing/issues/3","repository_url":"https://api.github.com/repos/icepy/we-writing","labels_url":"https://api.github.com/repos/icepy/we-writing/issues/3/labels{/name}","comments_url":"https://api.github.com/repos/icepy/we-writing/issues/3/comments","events_url":"https://api.github.com/repos/icepy/we-writing/issues/3/events","html_url":"https://github.com/icepy/we-writing/issues/3","id":116913265,"number":3,"title":"每周练习：在Swift中如何使用指针并操作指针","user":{"login":"icepy","id":3321837,"avatar_url":"https://avatars0.githubusercontent.com/u/3321837?v=4","gravatar_id":"","url":"https://api.github.com/users/icepy","html_url":"https://github.com/icepy","followers_url":"https://api.github.com/users/icepy/followers","following_url":"https://api.github.com/users/icepy/following{/other_user}","gists_url":"https://api.github.com/users/icepy/gists{/gist_id}","starred_url":"https://api.github.com/users/icepy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/icepy/subscriptions","organizations_url":"https://api.github.com/users/icepy/orgs","repos_url":"https://api.github.com/users/icepy/repos","events_url":"https://api.github.com/users/icepy/events{/privacy}","received_events_url":"https://api.github.com/users/icepy/received_events","type":"User","site_admin":false},"labels":[{"id":252099202,"url":"https://api.github.com/repos/icepy/we-writing/labels/Swift","name":"Swift","color":"eb6420","default":false}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2015-11-14T09:19:24Z","updated_at":"2017-10-06T17:36:29Z","closed_at":"2017-10-06T17:36:29Z","author_association":"OWNER","body":"**源代码基于 Swift 2.1+ Xcode 7.1.1编写**\n\n如果你还不了解指针，请先阅读[C语言指针5分钟教程](http://blog.jobbole.com/25409/)。\n\n在Swift中指针用两个特殊的类型来描述，UnsafePointer<T>和UnsafeMutablePointer<T>，遵循Cocoa的原则，可以看出`不可变`与`可变`的不同，当我们创建指针之后，就可以通过memory来操作指针了。另外，Swift中UnsafeBufferPointer<T>来描述一组连续的数据指针以及非完整结构不透明指针COpaquePointer\n\n**在函数中传递指针**\n\n在函数中传递指针有两种方式，一：使用`inout`关键字。二：使用Swift准备的指针类型。区别，我用注释写在具体的例子中。\n\n且先看看`inout`关键字，如何操作\n\n``` Swift\nvar num:Int = 10\nfunc some(inout numb:Int){\n    //如果使用inout关键字，在函数体内部不需要处理指针类型，可直接操作\n    numb += 1\n    print(\"numb --> \\(numb)\")\n}\nsome(&num)\nprint(\"num ---> \\(num)\")\n```\n\n使用Swift准备的指针类型\n\n``` Swift\nvar num:Int = 10\nfunc some(numb:UnsafeMutablePointer<Int>){\n    //如果使用Swift提供的类型，那么需要使用memory来进行操作\n    numb.memory += 1\n    print(\"numb --> \\(numb.memory)\")\n}\nsome(&num)\nprint(\"num ---> \\(num)\")\n```\n\n需要注意的是，Swift中地址符&是不能直接使用的，只能是函数传递时才可用。\n\n**如何直接操作**\n\n虽然无法像OC或者C中那样直接通过地址符&来操作指针，但是Swift也提供了辅助的方法间接的来帮助我们来操作指针。\n\n``` Swift\nvar i:Int = 10\ni = withUnsafeMutablePointer(&i, {\n   (p:UnsafeMutablePointer<Int>) -> Int in\n       p.memory += 20\n       return p.memory\n})\nprint(\"i value ---> \\(i)\")\n```\n\n**如何使用指向数组的指针**\n\n如果只是函数传递，不可变直接传递，可变使用&符即可，如果想直接操作，那么还是需要UnsafeBufferPointer<T>来辅助完成。\n\n``` Swift\nvar array:[Int] = [2,1,3,4]\nvar arrayPtr:UnsafeMutableBufferPointer<Int> = UnsafeMutableBufferPointer<Int>(start: &array, count: array.count)\nvar baseArrayPtr:UnsafeMutablePointer<Int> = arrayPtr.baseAddress as UnsafeMutablePointer<Int>\nvar nextPtr:UnsafeMutablePointer<Int> = baseArrayPtr.successor()\nvar threPtr:UnsafeMutablePointer<Int> = nextPtr.successor()\n\nprint(\"第一个元素  \\(baseArrayPtr.memory)\")\nprint(\"第二个元素 \\(nextPtr.memory)\")\nprint(\"第三个元素  \\(threPtr.memory)\")\n```\n\n**如何通过指针强制转换类型**\n\n这个操作比较危险，除非你明确预期知道类型，不然编译器是无法知道的，也就造成了非常大的不确定性。\n\n``` Swift\nlet arr:NSArray = NSArray(object: \"icepy\")\nlet str:NSString = unsafeBitCast(arr[0],NSString.self)\n\nprint(\"str --- > \\(str.stringByAppendingPathComponent(\"app\"))\")\n```\n\n**创建一个指针**\n\n``` Swift\n//创建可变指针\nvar i:UnsafeMutablePointer<String> = UnsafeMutablePointer<String>.alloc(10)\ni.initialize(\"icepy\")\n```\n\n**内存管理**\n\n还有一点要注意的是，如果是属于自己手动创建的指针，Swift是不负责管理内存的，需要手动的销毁与释放。\n\n一个UnsafeMutablePointer内存一般有三个状态：\n- 内存没有被分配，null指针\n- 内存进行了分配，且值还未初始化\n- 内存进行了分配，且值已经初始化\n\n``` Swift\nvar i:UnsafeMutablePointer<String> = UnsafeMutablePointer<String>.alloc(10)\ni.initialize(\"icepy\")        \nprint(\"i的内存地址 \\(i)\")\nprint(\"i的memory \\(i.memory)\")        \ni.destroy() //销毁指针指向的对象\ni.dealloc(10) //销毁指针申请的内存\ni = nil\n```\n## 【公告】\n\n---\n\n微信公众号开通于2016年，内容起于前端而不止于前端。讲技术，也分享生活。关注前沿，也注重实际的应用。前端是一个变革的领域，一起探索，一起学习，也一起在这个领域做些好玩的事情。\n\n**关注微信公众号，扫描二维码**\n\n<div align=\"center\">\n<img src=\"https://raw.githubusercontent.com/icepy/_posts/master/img/weixin.jpg\" alt=\"\"/><br>\n</div>\n"}}
{"actor":{"display_login":"icepy"}}