如何在swift 3中使用UnsafeMutablePointer <t?>

时间:2017-03-10 08:33:52

标签: swift swift-playground

我是Swift的新手,我不明白如何使用UnsafeMutablePointer<T?>。谁能帮助我?

struct TestStruct {
    var a = 0
}

func foo(ptr: UnsafeMutablePointer<TestStruct?>?) {
    ptr?.pointee?.a = 123 // pointee is nil, but why?
}

func bar(ptr: TestStruct?) {
    print("hello: \(ptr?.a)") // hello: nil
}

var ref = UnsafeMutablePointer<TestStruct?>.allocate(capacity: 1)

foo(ptr: ref)
bar(ptr: ref.pointee)

ref.deallocate(capacity: 1)

我为TestStruct分配内存,但当我将ref传递给foo时,pointee指向nil。如果我将TestStructUnsafeMutablePointer<TestStruct>)设为非可选项 - 一切都会很好 - 条形图hello: 123

更新

感谢@MartinR和@Hamish!工作代码:

struct TestStruct {
    var a = 0
}

func foo(ptr: UnsafeMutablePointer<TestStruct?>?) {
    ptr?.pointee?.a = 123
}

func bar(ptr: TestStruct?) {
    print("hello: \(ptr?.a)")
}

var ref = UnsafeMutablePointer<TestStruct?>.allocate(capacity: 1)

ref.initialize(to: TestStruct())

foo(ptr: ref)
bar(ptr: ref.pointee)


ref.deinitialize()
ref.deallocate(capacity: 1)

1 个答案:

答案 0 :(得分:1)

程序的行为未定义。

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SearchHotelsResponse xmlns="http://example.com/webservices/hotelasdfcgjk"> <SearchHotelsResult> <Info version="7.123" culture="en-US" serverTime="2017-03-01T07:31:08.9180701-05:00" xmlns="http://schemas.example.com/webservices/hotelasdlkjdft"/> <HotelList xmlns="http://schemas.example.com/webservices/hotelv3"> <Hotel brandId="141" brandName="Days Inn" category="Moderate" PropertySubType="" NumOfRoom="123" minAverPublishPrice="113.37" PropertyType="Hotel" name="Chrome Hotel Downtown Montreal - Demo" bestValue="false" hotelId="11856" provider="localTgsProvider" thumb="http://image1.urlforimages.com/Images/11856/100x100/1852921506.jpg" currency="CAD" minAverPrice="113.37" starsLevel="3" desc="Demo - Location&#xD;&#xA;The hotel is located in the heart of Montreal's cultural and business district in the city centre, within walking distance of Old Montreal, major attractions, festivals, restaurants, bars, shops and nightlife. The Latin Quarter, conventio"> <Location countryCode="CA" stateCode="QC" city="Montreal" searchingState="Quebec" searchingCity="Montreal" location="Downtown Area" address="Demo - 215 Boulevard Rene-Levesque East Montreal Quebec H2X 1N7" longitude="-73.5602601037048" latitude="45.5110178771468"/> <RoomTypes> <RoomType NumOfBathrooms="0" roomTypeCategory="Standard" roomTypeCategoryId="17" nights="7" name="Standard" productId="11856;11182;9356" startDate="2017-03-20T00:00:00" hotelRoomTypeId="11182" roomId="3" isAvailable="true"> <AvailabilityBreakdown> <Availability offset="0" status="true"/> <Availability offset="1" status="true"/> <Availability offset="2" status="true"/> <Availability offset="3" status="true"/> <Availability offset="4" status="true"/> <Availability offset="5" status="true"/> <Availability offset="6" status="true"/> </AvailabilityBreakdown> <Occupancies> <Occupancy taxPublish="126.7" avrNightPublishPrice="113.37" occupId="11856;11182;9356;2;2;0;1" occupPrice="793.59" tax="126.7" maxGuests="4" maxChild="2" avrNightPrice="113.37" occupPublishPrice="793.59" isPublish="false" bedding="2,1"> <PriceBreakdown> <Price offset="0" value="113.37" valuePublish="113.37"/> <Price offset="1" value="113.37" valuePublish="113.37"/> <Price offset="2" value="113.37" valuePublish="113.37"/> <Price offset="3" value="113.37" valuePublish="113.37"/> <Price offset="4" value="113.37" valuePublish="113.37"/> <Price offset="5" value="113.37" valuePublish="113.37"/> <Price offset="6" value="113.37" valuePublish="113.37"/> </PriceBreakdown> <Rooms> <Room seqNum="1"> <AdultNum>2</AdultNum> <ChildNum>0</ChildNum> </Room> </Rooms> <SelctedSupplements/> <BoardBases> <Boardbase bbId="1" bbName="Continental Breakfast" bbPrice="168.87" bbPublishPrice="168.87"/> </BoardBases> </Occupancy> <Occupancy taxPublish="126.7" avrNightPublishPrice="113.37" occupId="11856;11182;9356;2;2;0;2" occupPrice="793.59" tax="126.7" maxGuests="4" maxChild="2" avrNightPrice="113.37" occupPublishPrice="793.59" isPublish="false" bedding="2,2"> <PriceBreakdown> <Price offset="0" value="113.37" valuePublish="113.37"/> <Price offset="1" value="113.37" valuePublish="113.37"/> <Price offset="2" value="113.37" valuePublish="113.37"/> <Price offset="3" value="113.37" valuePublish="113.37"/> <Price offset="4" value="113.37" valuePublish="113.37"/> <Price offset="5" value="113.37" valuePublish="113.37"/> <Price offset="6" value="113.37" valuePublish="113.37"/> </PriceBreakdown> <Rooms> <Room seqNum="1"> <AdultNum>2</AdultNum> <ChildNum>0</ChildNum> </Room> </Rooms> <SelctedSupplements/> <BoardBases> <Boardbase bbId="1" bbName="Continental Breakfast" bbPrice="168.87" bbPublishPrice="168.87"/> </BoardBases> </Occupancy> </Occupancies> </RoomType> </RoomTypes> </Hotel> <Hotel brandId="0" brandName="" category="Superior First Class" PropertySubType="" NumOfRoom="108" minAverPublishPrice="226.33" PropertyType="Hotel" name="Le Saint Sulpice Hotel Montreal - Demo" bestValue="false" hotelId="1035988" provider="localTgsProvider" thumb="http://image1.urlforimages.com/Images/1035988/100x100/1476355076.jpg" currency="CAD" minAverPrice="226.33" starsLevel="4" desc="Demo - Location&#xD;&#xA;This attractive and comfortable city hotel is situated in the most historic area of Montreal, behind the famous basilica of Notre-Dame. Links to the public transport network lie 5 minutes' walk away, and the immediate vicinity also featur"> <Location countryCode="CA" stateCode="QC" city="Montreal" searchingState="Quebec" searchingCity="Montreal" location="Old Montreal" address="Demo - 414 Rue Saint Sulpice Montreal Quebec H2Y 2V5" longitude="-73.5549658932541" latitude="45.5043900016175"/> <RoomTypes> <RoomType NumOfBathrooms="0" roomTypeCategory="Suite" roomTypeCategoryId="19" nights="7" name="Superior Suite" productId="1035988;1121945;28111" startDate="2017-03-20T00:00:00" hotelRoomTypeId="1121945" roomId="410" isAvailable="true"> <AvailabilityBreakdown> <Availability offset="0" status="true"/> <Availability offset="1" status="true"/> <Availability offset="2" status="true"/> <Availability offset="3" status="true"/> <Availability offset="4" status="true"/> <Availability offset="5" status="true"/> <Availability offset="6" status="true"/> </AvailabilityBreakdown> <Occupancies> <Occupancy taxPublish="234.5" avrNightPublishPrice="226.33" occupId="1035988;1121945;28111;2;2;0;1" occupPrice="1584.31" tax="234.5" maxGuests="4" maxChild="2" avrNightPrice="226.33" occupPublishPrice="1584.31" isPublish="false" bedding="2,1"> <PriceBreakdown> <Price offset="0" value="226.33" valuePublish="226.33"/> <Price offset="1" value="226.33" valuePublish="226.33"/> <Price offset="2" value="226.33" valuePublish="226.33"/> <Price offset="3" value="226.33" valuePublish="226.33"/> <Price offset="4" value="226.33" valuePublish="226.33"/> <Price offset="5" value="226.33" valuePublish="226.33"/> <Price offset="6" value="226.33" valuePublish="226.33"/> </PriceBreakdown> <Rooms> <Room seqNum="1"> <AdultNum>2</AdultNum> <ChildNum>0</ChildNum> </Room> </Rooms> <SelctedSupplements/> <BoardBases> <Boardbase bbId="1" bbName="Continental Breakfast" bbPrice="277.14" bbPublishPrice="277.14"/> </BoardBases> </Occupancy> <Occupancy taxPublish="234.5" avrNightPublishPrice="226.33" occupId="1035988;1121945;28111;2;2;0;2" occupPrice="1584.31" tax="234.5" maxGuests="4" maxChild="2" avrNightPrice="226.33" occupPublishPrice="1584.31" isPublish="false" bedding="2,2"> <PriceBreakdown> <Price offset="0" value="226.33" valuePublish="226.33"/> <Price offset="1" value="226.33" valuePublish="226.33"/> <Price offset="2" value="226.33" valuePublish="226.33"/> <Price offset="3" value="226.33" valuePublish="226.33"/> <Price offset="4" value="226.33" valuePublish="226.33"/> <Price offset="5" value="226.33" valuePublish="226.33"/> <Price offset="6" value="226.33" valuePublish="226.33"/> </PriceBreakdown> <Rooms> <Room seqNum="1"> <AdultNum>2</AdultNum> <ChildNum>0</ChildNum> </Room> </Rooms> <SelctedSupplements/> <BoardBases> <Boardbase bbId="1" bbName="Continental Breakfast" bbPrice="277.14" bbPublishPrice="277.14"/> </BoardBases> </Occupancy> </Occupancies> </RoomType> <RoomType NumOfBathrooms="0" roomTypeCategory="Deluxe" roomTypeCategoryId="9" nights="7" name="Deluxe Queen" productId="1035988;1956583;28111" startDate="2017-03-20T00:00:00" hotelRoomTypeId="1956583" roomId="315" isAvailable="true"> <AvailabilityBreakdown> <Availability offset="0" status="true"/> <Availability offset="1" status="true"/> <Availability offset="2" status="true"/> <Availability offset="3" status="true"/> <Availability offset="4" status="true"/> <Availability offset="5" status="true"/> <Availability offset="6" status="true"/> </AvailabilityBreakdown> <Occupancies> <Occupancy taxPublish="270.55" avrNightPublishPrice="265.93" occupId="1035988;1956583;28111;2;2;0;1" occupPrice="1861.51" tax="270.55" maxGuests="4" maxChild="2" avrNightPrice="265.93" occupPublishPrice="1861.51" isPublish="false" bedding="2,1"> <PriceBreakdown> <Price offset="0" value="265.93" valuePublish="265.93"/> <Price offset="1" value="265.93" valuePublish="265.93"/> <Price offset="2" value="265.93" valuePublish="265.93"/> <Price offset="3" value="265.93" valuePublish="265.93"/> <Price offset="4" value="265.93" valuePublish="265.93"/> <Price offset="5" value="265.93" valuePublish="265.93"/> <Price offset="6" value="265.93" valuePublish="265.93"/> </PriceBreakdown> <Rooms> <Room seqNum="1"> <AdultNum>2</AdultNum> <ChildNum>0</ChildNum> </Room> </Rooms> <SelctedSupplements/> <BoardBases> <Boardbase bbId="1" bbName="Continental Breakfast" bbPrice="277.14" bbPublishPrice="277.14"/> </BoardBases> </Occupancy> <Occupancy taxPublish="294.63" avrNightPublishPrice="292.32" occupId="1035988;1956583;28111;2;2;0;2" occupPrice="2046.24" tax="294.63" maxGuests="4" maxChild="2" avrNightPrice="292.32" occupPublishPrice="2046.24" isPublish="false" bedding="2,2"> <PriceBreakdown> <Price offset="0" value="292.32" valuePublish="292.32"/> <Price offset="1" value="292.32" valuePublish="292.32"/> <Price offset="2" value="292.32" valuePublish="292.32"/> <Price offset="3" value="292.32" valuePublish="292.32"/> <Price offset="4" value="292.32" valuePublish="292.32"/> <Price offset="5" value="292.32" valuePublish="292.32"/> <Price offset="6" value="292.32" valuePublish="292.32"/> </PriceBreakdown> <Rooms> <Room seqNum="1"> <AdultNum>2</AdultNum> <ChildNum>0</ChildNum> </Room> </Rooms> <SelctedSupplements/> <BoardBases> <Boardbase bbId="1" bbName="Continental Breakfast" bbPrice="277.14" bbPublishPrice="277.14"/> </BoardBases> </Occupancy> </Occupancies> </RoomType> </RoomTypes> </Hotel> </HotelList> </SearchHotelsResult> </SearchHotelsResponse> </s:Body> </s:Envelope> 返回未初始化的内存:

allocate()

您必须在使用前对其进行初始化 (并在释放记忆之前取消初始化):

/// Allocates and points at uninitialized aligned memory for `count`
/// instances of `Pointee`.
///
/// - Postcondition: The pointee is allocated, but not initialized.
public static func allocate(capacity count: Int) -> UnsafeMutablePointer<Pointee>

这是另一个没有实际初始化内存的例子 导致崩溃:

let ref = UnsafeMutablePointer<TestStruct?>.allocate(capacity: 1)
ref.initialize(to: TestStruct())

foo(ptr: ref)
bar(ptr: ref.pointee)

ref.deinitialize()
ref.deallocate(capacity: 1)

赋值语句期望class TestClass { init() { print("init") } deinit { print("deinit") } } let ptr = UnsafeMutablePointer<TestClass>.allocate(capacity: 1) ptr.pointee = TestClass() 处于初始化状态 并指向ptr.pointee实例。因为ARC(自动 引用计数),先前指向的对象是发布 在分配新值时。如果TestClass,则会崩溃 初始化。